Sign up - or - Login

Recover password
×

To recover your password, you must enter the username or e-mail that you used during the registration. After that, a mail with a security code will be sent to your inbox.

Your username or e-mail :

BRUTAL HALF-LIFEBRUTAL HALF-LIFE

Мод, вдохновленный Brutal Doom. Время мочилова!...

19/03/2015
Stat ( source prefabs ), pcs.

Играя в Халф-Лайф, вы не задумывались над тем, что в нем чего-то не хватает? Чего-то очень близкого, родного, горячего...


  • Description
  • HOW TO INSTALL

weapon_flamethrower

Играя в Халф-Лайф, вы не задумывались над тем, что в нем чего-то не хватает? Чего-то очень близкого, родного, горячего...


Author/s of tutorial : Ghoul [BB]
Views : 3732 ( +1 )
Downloads : 0
Uploader : Streit
Created : 04/07/2011 8:36:58 PM
Source : http://www.half-life.ru/forum
Rating :
 ( 1 ) 
Share :


Following translations are available : | russian |

Играя в Халф-Лайф, вы не задумывались над тем, что в нем чего-то не хватает? Чего-то очень близкого, родного, горячего… Представленные в игре виды оружия удовлетворят самый изощренный вкус - тут и стандартный огнестрел, и переносная ракетница, и всевозможные энерго-экспериментальные футуристические пушки, и даже такая экзотика, как биооружие Чужих… Но ЭТОГО еще не было! Знакомьтесь: ОГНЕМЕТ! Огнемет это - друг пожарников, пироманов и просто тех, кому стало слишком холодно.

Ниже приведена подробная инструкция по кодингу и дальнейшей эксплуатации сего девайса! Итак, начнем.

  1. Сначала создадим сам "огонь": Клиентная часть. cl_dll/hl/hl_baseentity.cpp Ищем:

Code:

// CGrenade Stubs
void CGrenade::BounceSound( void ) { }

Добавляем ниже:

Code:

// CFlame
void CFlame::BounceSound( void ) { }
void CFlame::Explode( Vector, Vector ) { }
void CFlame::Explode( TraceResult *, int ) { }
void CFlame::Killed( entvars_t *, int ) { }
void CFlame::Spawn( void ) { }
CFlame*CFlame::ShootFlame( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ){ return 0; }
  1. Переходим теперь к серверной части (т.е. dlls) Откроем файл weapons.h И найдем:

Code:

class CGrenade : public CBaseMonster
{
   public:
   void Spawn( void );

Добавим после этого класса ( после }; ):

Code:

class CFlame : public CBaseMonster
{
   public:
   static CFlame *ShootFlame( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity );

   void Spawn( void );
   void Explode( Vector vecSrc, Vector vecAim );
   void Explode( TraceResult *pTrace, int bitsDamageType );
   void EXPORT Smoke( void );

   void EXPORT BounceTouch( CBaseEntity *pOther );
   void EXPORT SlideTouch( CBaseEntity *pOther );
   void EXPORT ExplodeTouch( CBaseEntity *pOther );
   void EXPORT DangerSoundThink( void );
   void EXPORT PreDetonate( void );
   void EXPORT Detonate( void );
   void EXPORT DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );

   virtual void BounceSound( void );
   virtual int BloodColor( void ) { return DONT_BLEED; }
   virtual void Killed( entvars_t *pevAttacker, int iGib );

   BOOL m_fRegisteredSound;
};
  1. Регистрация ресурсов: В weapons.cpp найдем:

Code:

DLL_GLOBAL short g_sModelIndexFireball;// holds the index for the fireball

Добавим:

Code:

DLL_GLOBAL short g_sModelIndexFlame;// Flamethrower flame

Ниже найдем:

Code:

g_sModelIndexFireball = PRECACHE_MODEL ("sprites/zerogxplode.spr");// fireball

Добавим:

Code:

g_sModelIndexFlame = PRECACHE_MODEL ("sprites/flame.spr");// Flamethrower

Теперь откроем weapons.h и найдем:

Code:

extern DLL_GLOBAL short g_sModelIndexFireball;// holds the index for the fireball

Добавим:

Code:

extern DLL_GLOBAL short g_sModelIndexFlame;// flame

С регистрацией огня, вроде, все.

  1. Создадим новую переменную для skill.cfg, указывающую на ущерб огнемета. Откроем game.cpp и найдем:

Code:

// RPG
cvar_t sk_plr_rpg1 = {"sk_plr_rpg1","0"};
cvar_t sk_plr_rpg2 = {"sk_plr_rpg2","0"};
cvar_t sk_plr_rpg3 = {"sk_plr_rpg3","0"};

Добавим ниже:

Code:

// Flamethrower
cvar_t sk_plr_flamethrower1 = {"sk_plr_flamethrower1","0"};
cvar_t sk_plr_flamethrower2 = {"sk_plr_flamethrower2","0"};
cvar_t sk_plr_flamethrower3 = {"sk_plr_flamethrower3","0"};

В этом же файле ниже найдем:

Code:

// RPG
CVAR_REGISTER ( &sk_plr_rpg1 );
CVAR_REGISTER ( &sk_plr_rpg2 );
CVAR_REGISTER ( &sk_plr_rpg3 );

И добавим:

Code:

//Flamethrower
CVAR_REGISTER ( &sk_plr_flamethrower1 );
CVAR_REGISTER ( &sk_plr_flamethrower2 );
CVAR_REGISTER ( &sk_plr_flamethrower3 );

Все. Открываем gamerules.cpp и ищем:

Code:

// RPG
gSkillData.plrDmgRPG = GetSkillCvar( "sk_plr_rpg");

Ставим:

Code:

//flamethrower
gSkillData.plrDmgFlamethrower = GetSkillCvar( "sk_plr_flamethrower");

Все. Теперь обратим наш взор на skill.h, где найдем строку:

Code:

float plrDmgRPG;

И добавим:

Code:

float plrDmgFlamethrower;

С регистрацией все. Теперь осталось открыть skill.cfg и вставить:

Code:

// Flamethrower
sk_plr_flamethrower1 "12"
sk_plr_flamethrower2 "12"
sk_plr_flamethrower3 "12"

(не думайте, что 12 ущерба - это мало, ибо огнемет у нас будет стрелять сразу 6 сгустками вот такого огня…)

  1. Теперь регистрируем новый тип боеприпасов: В cbase.h ищем:

Code:

int ammo_rockets;

Добавляем:

Code:

int ammo_fuel;

Переходим в client.cpp и ищем:

Code:

cd->ammo_rockets = pl->ammo_rockets;

Добавим ниже:

Code:

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

Напоследок переходим в player.cpp, где найдем:

Code:

ammo_rockets = AmmoInventory( GetAmmoIndex( "rockets" ) );

Добавим:

Code:

ammo_fuel = AmmoInventory( GetAmmoIndex( "fuel" ) );

Напоследок не забываем заглянуть в weapons.h, где объявляем новое количество боезапаса: Ищем:

Code:

#define ROCKET_MAX_CARRY 5

Ставим:

Code:

#define _FUEL_MAX_CARRY 250

ВСЕ!

  1. Теперь переходим к самому главному - регистрации нового класса оружия. Остаемся в файле weapons.h, где находим:

Code:

#define WEAPON_SNARK 15

И добавляем:

Code:

#define WEAPON_flamethrower 16

Чуть ниже ставим вес оружия, ищем:

Code:

#define RPG_WEIGHT 20

Ставим:

Code:

#define FLAMETHROWER_WEIGHT 40

Теперь переходим к weapons.cpp, где ищем:

Code:

// gauss
UTIL_PrecacheOtherWeapon( "weapon_gauss" );
UTIL_PrecacheOther( "ammo_gaussclip" );

Ниже ставим:

Code:

// Flamethrower
UTIL_PrecacheOtherWeapon( "weapon_flamethrower" );
UTIL_PrecacheOther( "ammo_fuel" );

Можно добавить еще в player.cpp, после:

Code:

GiveNamedItem( "weapon_357" );

Добавим:

Code:

GiveNamedItem( "weapon_flamethrower" );

Это с читом импульс 101 даем огнемет.

Ну вот. Теперь главное - код пламени: создадим файл и обзовем его flame.cpp:

Code:

#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "soundent.h"
#include "decals.h"

LINK_ENTITY_TO_CLASS( flamethrower_flame, CFlame );

void CFlame::Explode( Vector vecSrc, Vector vecAim )
{
   TraceResult tr;
   UTIL_TraceLine ( pev->origin, pev->origin + Vector ( 0, 0, -32 ), ignore_monsters, ENT(pev), & tr);

   Explode( &tr, DMG_BURN );
}

void CFlame::Explode( TraceResult *pTrace, int bitsDamageType )
{
   float flRndSound;

   pev->model = iStringNull;
   pev->solid = SOLID_NOT;

   pev->takedamage = DAMAGE_NO;

   // Pull out of the wall a bit
   if ( pTrace->flFraction != 1.0 )
   {
     pev->origin = pTrace->vecEndPos + (pTrace->vecPlaneNormal * 60);
   }

   int iContents = UTIL_PointContents ( pev->origin );

   MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
   WRITE_BYTE( TE_EXPLOSION );
   WRITE_COORD( pev->origin.x );
   WRITE_COORD( pev->origin.y );
   WRITE_COORD( pev->origin.z );
   WRITE_SHORT( g_sModelIndexFlame );
   WRITE_BYTE( 10 );
   WRITE_BYTE( 15 );
   WRITE_BYTE( TE_EXPLFLAG_NOSOUND );
   MESSAGE_END();

   MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
   WRITE_BYTE( TE_DLIGHT );
   WRITE_COORD( pev->origin.x );
   WRITE_COORD( pev->origin.y );
   WRITE_COORD( pev->origin.z );
   WRITE_BYTE( 50 );
   WRITE_BYTE( 220 );
   WRITE_BYTE( 150 );
   WRITE_BYTE( 0 );
   WRITE_BYTE( 10 );
   WRITE_BYTE( 10 );
   MESSAGE_END();

   CSoundEnt::InsertSound ( bits_SOUND_COMBAT, pev->origin, BIG_EXPLOSION_VOLUME, 3.0 );
   entvars_t *pevOwner;
   if ( pev->owner )
     pevOwner = VARS( pev->owner );
   else
     pevOwner = NULL;

   pev->owner = NULL;

   ::RadiusDamage( pev->origin, pev, pevOwner, pev->dmg, 175, CLASS_NONE, DMG_BURN );

   if ( RANDOM_FLOAT( 0 , 1 ) < 0.5 )
   {
     UTIL_DecalTrace( pTrace, DECAL_SMALLSCORCH1 );
   }
   else
   {
     UTIL_DecalTrace( pTrace, DECAL_SMALLSCORCH3 );
   }

   flRndSound = RANDOM_FLOAT( 0 , 1 );

   EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/flame_hitwall.wav", 0.55, ATTN_NORM);

   pev->effects |= EF_NODRAW;
   pev->velocity = g_vecZero;
   SetThink( Smoke );
   pev->nextthink = gpGlobals->time + 0.1;
}

void CFlame::Smoke( void )
{
   if (UTIL_PointContents ( pev->origin ) == CONTENTS_WATER)
   {
     UTIL_Bubbles( pev->origin - Vector( 64, 64, 64 ), pev->origin + Vector( 64, 64, 64 ), 100 );
   }
   else
   {
     MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
     WRITE_BYTE( TE_SMOKE );
     WRITE_COORD( pev->origin.x );
     WRITE_COORD( pev->origin.y );
     WRITE_COORD( pev->origin.z );
     WRITE_SHORT( g_sModelIndexSmoke );
     WRITE_BYTE( 10 );
     WRITE_BYTE( 6 );
     MESSAGE_END();
   }
   UTIL_Remove( this );
}

void CFlame::Killed( entvars_t *pevAttacker, int iGib )
{
   Detonate( );
}


void CFlame::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
   SetThink( Detonate );
   pev->nextthink = gpGlobals->time;
}

void CFlame::PreDetonate( void )
{
   CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, 400, 0.3 );

   SetThink( Detonate );
   pev->nextthink = gpGlobals->time + 1;
}


void CFlame::Detonate( void )
{
   TraceResult tr;
   Vector vecSpot;

   vecSpot = pev->origin + Vector ( 0 , 0 , 8 );
   UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -40 ), ignore_monsters, ENT(pev), & tr);

   Explode( &tr, DMG_BURN );

}


void CFlame::ExplodeTouch( CBaseEntity *pOther )
{
   TraceResult tr;
   Vector vecSpot;

   pev->enemy = pOther->edict();

   vecSpot = pev->origin - pev->velocity.Normalize() * 32;
   UTIL_TraceLine( vecSpot, vecSpot + pev->velocity.Normalize() * 64, ignore_monsters, ENT(pev), &tr );

   Explode( &tr, DMG_BURN );
}

void CFlame::DangerSoundThink( void )
{
   if (!IsInWorld())
   {
     UTIL_Remove( this );
     return;
   }

   CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, pev->velocity.Length( ), 0.2 );
   pev->nextthink = gpGlobals->time + 0.2;

   if (pev->waterlevel != 0)
   {
     pev->velocity = pev->velocity * 0.5;
   }
}

void CFlame::BounceTouch( CBaseEntity *pOther )
{
   if ( pOther->edict() == pev->owner )
     return;

   if (m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 100)
   {
     entvars_t *pevOwner = VARS( pev->owner );
     if (pevOwner)
     {
       TraceResult tr = UTIL_GetGlobalTrace( );
       ClearMultiDamage( );
       pOther->TraceAttack(pevOwner, 1, gpGlobals->v_forward, &tr, DMG_CLUB );
       ApplyMultiDamage( pev, pevOwner);
     }
     m_flNextAttack = gpGlobals->time + 1.0;
   }

   Vector vecTestVelocity;
   vecTestVelocity = pev->velocity;
   vecTestVelocity.z *= 0.45;

   if ( !m_fRegisteredSound && vecTestVelocity.Length() <= 60 )
   {
     CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3 );
     m_fRegisteredSound = TRUE;
   }

   if (pev->flags & FL_ONGROUND)
   {
     pev->velocity = pev->velocity * 0.8;

     pev->sequence = RANDOM_LONG( 1, 1 );
   }
   else
   {
     BounceSound();
   }
   pev->framerate = pev->velocity.Length() / 200.0;
   if (pev->framerate > 1.0)
     pev->framerate = 1;
   else if (pev->framerate < 0.5)
     pev->framerate = 0;

}

void CFlame::SlideTouch( CBaseEntity *pOther )
{
   if ( pOther->edict() == pev->owner )
     return;

   if (pev->flags & FL_ONGROUND)
   {
     pev->velocity = pev->velocity * 0.95;

     if (pev->velocity.x != 0 || pev->velocity.y != 0)
     {
     }
   }
   else
   {
     BounceSound();
   }
}

void CFlame :: BounceSound( void )
{
   EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/flame_hitwall.wav", 0.25, ATTN_NORM);
}

void CFlame:: Spawn( void )
{
   pev->movetype = MOVETYPE_BOUNCE;
   pev->classname = MAKE_STRING( "flamethrower_flame" );

   pev->solid = SOLID_BBOX;

   SET_MODEL(ENT(pev), "sprites/flamesteam.spr");
   pev->rendermode = kRenderTransAdd;
   pev->rendercolor.x = 255;
   pev->rendercolor.y = 255;
   pev->rendercolor.z = 255;
   pev->renderamt = 255;
   if ( RANDOM_FLOAT( 0 , 1 ) < 0.5 )
   {
     pev->scale = 1;
   }
   else
   {
     pev->scale = 2;
   }

   UTIL_SetSize(pev, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ) );

   pev->dmg = gSkillData.plrDmgFlamethrower;
   m_fRegisteredSound = FALSE;
}

CFlame *CFlame::ShootFlame( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity )
{
   CFlame *pFlame = GetClassPtr( (CFlame *)NULL );
   pFlame->Spawn();

   pFlame->pev->gravity = 1.5;
   UTIL_SetOrigin( pFlame->pev, vecStart );
   pFlame->pev->velocity = vecVelocity;
   pFlame->pev->angles = UTIL_VecToAngles (pFlame->pev->velocity);
   pFlame->pev->owner = ENT(pevOwner);

   pFlame->SetThink( DangerSoundThink );
   pFlame->pev->nextthink = gpGlobals->time;

   pFlame->SetTouch( ExplodeTouch );

   pFlame->pev->dmg = gSkillData.plrDmgFlamethrower;

   return pFlame;
}

Теперь с самим огнеметом: Создадим flamethrower.cpp

Code:

#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 flamethrower_e
{
   FLAMETHROWER_LONGIDLE,
   FLAMETHROWER_IDLE1,
   FLAMETHROWER_RELOAD,
   FLAMETHROWER_DEPLOY,
   FLAMETHROWER_HOLSTER,
   FLAMETHROWER_SHOOT,
};

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

   void PrimaryAttack( void );
   BOOL Deploy( void );
   void Holster( int skiplocal = 0 );
   void Reload( void );
   void WeaponIdle( void );
   float m_flNextAnimTime;
};
LINK_ENTITY_TO_CLASS( weapon_flamethrower, CFLAMETHROWER );

void CFLAMETHROWER::Spawn( )
{
   pev->classname = MAKE_STRING("weapon_flamethrower");
   Precache( );
   SET_MODEL(ENT(pev), "models/w_flamethrower.mdl");
   m_iId = WEAPON_flamethrower;

   m_iDefaultAmmo = 100;

   FallInit();
}


void CFLAMETHROWER::Precache( void )
{
   PRECACHE_MODEL("models/v_flamethrower.mdl");
   PRECACHE_MODEL("models/w_flamethrower.mdl");
   PRECACHE_MODEL("models/p_flamethrower.mdl");
   PRECACHE_MODEL("sprites/flamesteam.spr");

   PRECACHE_MODEL("models/w_flamefuel.mdl");
   PRECACHE_SOUND("items/9mmclip1.wav");

   PRECACHE_SOUND("weapons/flamethrower_reload.wav");
   PRECACHE_SOUND("weapons/flame_hitwall.wav");
   PRECACHE_SOUND("items/clipinsert1.wav");
   PRECACHE_SOUND("items/cliprelease1.wav");
   PRECACHE_SOUND ("weapons/flamethrower.wav");

   PRECACHE_SOUND ("weapons/357_cock1.wav");
   m_flNextPrimaryAttack = gpGlobals->time + 0.5;
}

int CFLAMETHROWER::GetItemInfo(ItemInfo *p)
{
   p->pszName = STRING(pev->classname);
   p->pszAmmo1 = "fuel";
   p->iMaxAmmo1 = _FUEL_MAX_CARRY;
   p->pszAmmo2 = NULL;
   p->iMaxAmmo2 = -1;
   p->iMaxClip = 100;
   p->iSlot = 4;
   p->iPosition = 4;
   p->iFlags = 0;
   p->iId = m_iId = WEAPON_flamethrower;
   p->iWeight = FLAMETHROWER_WEIGHT;

   return 1;
}

int CFLAMETHROWER::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 CFLAMETHROWER::Deploy( )
{
   return DefaultDeploy( "models/v_flamethrower.mdl", "models/p_flamethrower.mdl", FLAMETHROWER_DEPLOY, "mp5" );
}

void CFLAMETHROWER::Holster( int skiplocal )
{
   SendWeaponAnim( FLAMETHROWER_HOLSTER );
}

void CFLAMETHROWER::PrimaryAttack( void )
{
   if (m_pPlayer->pev->waterlevel == 3)
   {
     PlayEmptySound( );
     m_flNextPrimaryAttack = gpGlobals->time + 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--;

   SendWeaponAnim( FLAMETHROWER_SHOOT );

   m_pPlayer->SetAnimation( PLAYER_ATTACK1 );

   EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/flamethrower.wav", 0.8, ATTN_NORM);

   UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle );

   CFlame::ShootFlame( m_pPlayer->pev,
m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 16 + gpGlobals->v_right * 5 + gpGlobals->v_up * -10,
gpGlobals->v_forward * 900 );

   CFlame::ShootFlame( m_pPlayer->pev,
m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 16 + gpGlobals->v_right * 10 + gpGlobals->v_up * -15,
gpGlobals->v_forward * 920 );

   CFlame::ShootFlame( m_pPlayer->pev,
m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 24 + gpGlobals->v_right * 15 + gpGlobals->v_up * -20,
gpGlobals->v_forward * 940 );

   CFlame::ShootFlame( m_pPlayer->pev,
m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 24 + gpGlobals->v_right * 5 + gpGlobals->v_up * -10,
gpGlobals->v_forward * 960 );

   CFlame::ShootFlame( m_pPlayer->pev,
m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 32 + gpGlobals->v_right * 10 + gpGlobals->v_up * -15,
gpGlobals->v_forward * 980 );

   CFlame::ShootFlame( m_pPlayer->pev,
m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 32 + gpGlobals->v_right * 15 + gpGlobals->v_up * -20,
gpGlobals->v_forward * 1000 );

   MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
   WRITE_BYTE( TE_DLIGHT );
   WRITE_COORD( pev->origin.x );
   WRITE_COORD( pev->origin.y );
   WRITE_COORD( pev->origin.z );
   WRITE_BYTE( 75 );
   WRITE_BYTE( 128 );
   WRITE_BYTE( 128 );
   WRITE_BYTE( 0 );
   WRITE_BYTE( 5 );
   WRITE_BYTE( 10 );
   MESSAGE_END();

   m_flNextPrimaryAttack = gpGlobals->time + 0.1;
   m_flTimeWeaponIdle = gpGlobals->time + 5;

   m_pPlayer->pev->punchangle.x -= 1;
}

void CFLAMETHROWER::Reload( void )
{
   int iResult;

   if ( m_iClip == 100 )
   {
     m_flNextPrimaryAttack = gpGlobals->time + 0.5;

     return;
   }

   if (m_iClip == 0)
   {
     iResult = DefaultReload( 100, FLAMETHROWER_RELOAD, 4.3 );
     EMIT_SOUND(ENT(pev), CHAN_ITEM, "weapons/flamethrower_reload.wav", 1, ATTN_NORM);
   }

   if (iResult)
   {
     m_flTimeWeaponIdle = gpGlobals->time + RANDOM_FLOAT ( 10, 15 );
   }
}

void CFLAMETHROWER::WeaponIdle( void )
{
   ResetEmptySound( );

   m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );

   if (m_flTimeWeaponIdle > gpGlobals->time)
     return;

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

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

   SendWeaponAnim( iAnim );

   m_flTimeWeaponIdle = gpGlobals->time + RANDOM_FLOAT ( 10, 15 );
}

class CFLAMETHROWERAmmo : public CBasePlayerAmmo
{
   void Spawn( void )
   {
     Precache( );
     SET_MODEL(ENT(pev), "models/w_flamefuel.mdl");
     CBasePlayerAmmo::Spawn( );
   }
   void Precache( void )
   {
     PRECACHE_MODEL ("models/w_flamefuel.mdl");
     PRECACHE_SOUND("items/9mmclip1.wav");
   }
   BOOL AddAmmo( CBaseEntity *pOther )
   {
     int bResult = (pOther->GiveAmmo( 50, "fuel", _FUEL_MAX_CARRY ) != -1);

     if (bResult)
     {
       EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM);
     }
     return bResult;
   }
};
LINK_ENTITY_TO_CLASS( ammo_fuel, CFLAMETHROWERAmmo );

Усё!

В следующем файле - все необходимые ресурсы - модели, спрайты, etc.

З.Ы. Не судите строго, если я что забыл сюда написать или чего-то криво объяснил…

Итак, удачи!

Примечание редактора: Внимание! Компилировать клиент нужно только после компиляции сервера! Т.е. в первой части надо просто внести изменения на клиенте и сохранить их, иначе будут ошибки типа: error C2653: CFlame : is not a class or namespace name.



Similar1. Добавление ножа из Op4 - Добавление ножа из Op4
2. Летающие бочки и trigger_push - Все, кто хотя бы один раз прошел Hl1 наверняка знает, что на карте c2a5 (там где плотина) есть такие прикольные бочки, которые подскакивают вверх и там взрываются.
3. Больше слотов и позиций для оружия - Больше слотов и позиций для оружия
4. Изменение цвета HUD'а (полное)! - Изменение цвета HUD'а (полное)! Но прицелы придётся переделывать вам самим! Сдесь я перевевёл туториал с twhl.info на русский язык!
SuperSpore 04/29/2012, 3:35:41 AM commented :
#1
Дай сыллку плиз!
Vlagamer 11/26/2022, 6:47:59 AM commented :
#2
Пайро доволен
You cannot comment, because you are not logged-in.
    The Bridge (Раздача в EpicGamesStore)
    The Bridge (Раздача в EpicGamesStore)
    Astro Duel 2 (Раздача в EpicGamesStore)
    Astro Duel 2 (Раздача в EpicGamesStore)
    Space Crew: Legendary Edition (Раздача в Steam)
    Space Crew: Legendary Edition (Раздача в Steam)
    ГАЗ 14
    Half-LifeГАЗ 14