Приветствую Вас 1-класс | RSS Главная | Каталог статей | Регистрация | Вход
Меню сайта

Категории раздела
Программирование [7]
Моделирование [8]
Маппинг [67]
Текстурирование [10]

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Мини чат

Главная » Статьи » Программирование

weapon_binoculars
Binoculars

Привет всем кто читает эту статью! Тут рассказывается про то, как создать бинокль для Half-Life 2. Итак поехали! Сначала создайте в серверной части кода (src/dlls/hl2_dll/) файлик под названием weapon_binoculars.cpp и туда впишите вот это:

//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============

//

// Purpose: Implements binoculars.

//

// Primary attack button: zoom in.

// Secondary attack button: zoom out.

//

// UNDONE: Black mask around view when zoomed in.

// UNDONE: New reticle & hud effects.

// UNDONE: Animated zoom effect?

//

// $NoKeywords: $

//=============================================================================

#include "cbase.h"

#include "NPCEvent.h"

#include "basehlcombatweapon.h"

#include "basecombatcharacter.h"

#include "AI_BaseNPC.h"

#include "player.h"

#include "gamerules.h" // For g_pGameRules

#include "entitylist.h"

#include "soundenvelope.h"

#include "in_buttons.h"

#include "engine/IEngineSound.h"

#define BINOCULARS_MAXSOURCES 50

#define BINOCULARS_CACHEFREQ 1.0

#define BINOCULARS_FAKEDIST 99999

#define BINOCULARS_VIEWCONE 0.6

#define BINOCULARS_ZOOM_RATE 0.15 // Interval between zoom levels in seconds.

#define WB_STATIC_CHANNEL CHAN_VOICE

#define WB_SIGNAL_CHANNEL CHAN_BODY

enum ZoomMode_t

{

Zoom_Exit = 0,

Zoom_In,

Zoom_Out

};

//-----------------------------------------------------------------------------

// Discrete zoom levels for the scope.

//-----------------------------------------------------------------------------

static int g_nZoomFOV[] =

{

0,

40,

30,

20,

10,

5

};

class CWeaponBinoculars : public CBaseHLCombatWeapon

{

public:

DECLARE_CLASS( CWeaponBinoculars, CBaseHLCombatWeapon );

DECLARE_SERVERCLASS();

void Spawn( void );

CWeaponBinoculars( void );

~CWeaponBinoculars( void );

void Precache( void );

int CapabilitiesGet( void );

bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );

void ItemPostFrame( void );

void Zoom( ZoomMode_t eMode );

bool Deploy( void );

void CacheSoundSources( void );

CBaseEntity *LocateBestSound( void );

float GetSoundDist( CBaseEntity *pSound, const Vector &vecLOS );

protected:

CSoundPatch *m_pSoundStatic;

CSoundPatch *m_pSoundSignal;

float m_fNextZoom;

int m_nZoomLevel;

static const char *pStaticSounds[];

static const char *pSignalSounds[];

float m_NextCacheTime;

EHANDLE m_hSources[ BINOCULARS_MAXSOURCES ];

DECLARE_DATADESC();

};

IMPLEMENT_SERVERCLASS_ST(CWeaponBinoculars, DT_WeaponBinoculars)

END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( weapon_binoculars, CWeaponBinoculars );

PRECACHE_WEAPON_REGISTER(weapon_binoculars);

//---------------------------------------------------------

//---------------------------------------------------------

BEGIN_DATADESC( CWeaponBinoculars )

DEFINE_FIELD( m_NextCacheTime, FIELD_TIME ),

DEFINE_SOUNDPATCH( m_pSoundSignal ),

DEFINE_SOUNDPATCH( m_pSoundStatic ),

DEFINE_FIELD( m_fNextZoom, FIELD_FLOAT ),

DEFINE_FIELD( m_nZoomLevel, FIELD_INTEGER ),

DEFINE_ARRAY( m_hSources, FIELD_EHANDLE, BINOCULARS_MAXSOURCES ),

END_DATADESC()

//---------------------------------------------------------

//---------------------------------------------------------

void CWeaponBinoculars::Spawn( void )

{

BaseClass::Spawn();

int i;

for( i = 0 ; i < BINOCULARS_MAXSOURCES ; i++ )

{

m_hSources[ i ] = NULL;

}

}

//-----------------------------------------------------------------------------

// Binocular radio sounds

//-----------------------------------------------------------------------------

const char *CWeaponBinoculars::pStaticSounds[] =

{

// These sounds are played constantly whilst the binoculars are

// in use.

"weapons/binoculars/buzz.wav",

};

//---------------------------------------------------------

//---------------------------------------------------------

const char *CWeaponBinoculars::pSignalSounds[] =

{

// These sounds play when the binoculars are nearly locked onto a signal

"weapons/binoculars/signal.wav",

};

//-----------------------------------------------------------------------------

// Only need to call this every second or so WHEN the binoculars are zoomed in.

//-----------------------------------------------------------------------------

void CWeaponBinoculars::CacheSoundSources( void )

{

EHANDLE *pSources = m_hSources;

CBaseEntity *pEnt;

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

Assert( pPlayer != NULL );

if (pPlayer == NULL)

{

return;

}

pEnt = UTIL_EntitiesInPVS( pPlayer, NULL );

int count = 0;

while( pEnt )

{

if( pEnt->IsSoundSource() )

{

*pSources = pEnt;

pSources++;

count++;

}

if( count == ( BINOCULARS_MAXSOURCES - 1 ) )

{

Msg( "*** BINOCULARS: TOO MANY SOUND SOURCES!\n" );

break;

}

pEnt = UTIL_EntitiesInPVS( pPlayer, pEnt );

}

pSources = NULL;

m_NextCacheTime = gpGlobals->curtime + BINOCULARS_CACHEFREQ;

}

//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

bool CWeaponBinoculars::Deploy()

{

// Ensure that we cache sounds as soon as the binoculars zoom in.

m_NextCacheTime = gpGlobals->curtime;

CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();

// Create our sounds the first time we're used

if ( !m_pSoundStatic || !m_pSoundSignal )

{

CPASAttenuationFilter filter( this, ATTN_NONE );

m_pSoundStatic = controller.SoundCreate( filter, entindex(), WB_STATIC_CHANNEL, pStaticSounds[ 0 ], ATTN_NONE );

m_pSoundSignal = controller.SoundCreate( filter, entindex(), WB_SIGNAL_CHANNEL, pSignalSounds[ 0 ], ATTN_NONE );

}

controller.CommandClear( m_pSoundStatic );

controller.CommandClear( m_pSoundSignal );

controller.Play( m_pSoundStatic, 0.0, 100 );

controller.Play( m_pSoundSignal, 0.0, 100 );

return BaseClass::Deploy();

}

//-----------------------------------------------------------------------------

// Purpose: Constructor.

//-----------------------------------------------------------------------------

CWeaponBinoculars::CWeaponBinoculars( void )

{

m_fNextZoom = gpGlobals->curtime;

m_nZoomLevel = 0;

m_pSoundStatic = NULL;

m_pSoundSignal = NULL;

}

//-----------------------------------------------------------------------------

// Purpose: Destructor - Free the sound resources we allocate in Spawn()

//-----------------------------------------------------------------------------

CWeaponBinoculars::~CWeaponBinoculars( void )

{

CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();

controller.SoundDestroy( m_pSoundStatic );

controller.SoundDestroy( m_pSoundSignal );

}

//-----------------------------------------------------------------------------

// Purpose:

// Output : int

//-----------------------------------------------------------------------------

int CWeaponBinoculars::CapabilitiesGet( void )

{

return 0;

}

//-----------------------------------------------------------------------------

// Purpose: Turns off the zoom when the binoculars are holstered.

//-----------------------------------------------------------------------------

bool CWeaponBinoculars::Holster( CBaseCombatWeapon *pSwitchingTo )

{

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if ( pPlayer != NULL )

{

if ( m_nZoomLevel != 0 )

{

pPlayer->ShowViewModel(true);

pPlayer->SetFOV( this, 0 );

m_nZoomLevel = 0;

}

}

CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();

controller.SoundDestroy( m_pSoundStatic );

controller.SoundDestroy( m_pSoundSignal );

m_pSoundStatic = NULL;

m_pSoundSignal = NULL;

return true;

}

//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

float CWeaponBinoculars::GetSoundDist( CBaseEntity *pSound, const Vector &vecLOS )

{

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if ( !pPlayer )

return 0.0f;

Vector vecDirToSound;

float flDot;

float flDist;

vecDirToSound = pSound->GetAbsOrigin() - pPlayer->GetAbsOrigin();

VectorNormalize(vecDirToSound);

flDot = DotProduct( vecDirToSound, vecLOS );

if( flDot < BINOCULARS_VIEWCONE )

{

// Don't bother with sounds outside of a reasonable viewcone

return BINOCULARS_FAKEDIST;

}

flDist = ( pSound->GetAbsOrigin() - pPlayer->GetAbsOrigin() ).Length();

return flDist * (1.0 - flDot);

}

//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

CBaseEntity *CWeaponBinoculars::LocateBestSound( void )

{

// go through the sound list and find the sound the player is probably trying to listen to.

EHANDLE *pIterate;

CBaseEntity *pBestSound = NULL;

float flBestSoundDist;

float flTestDist;

Vector vecLOS;

flBestSoundDist = BINOCULARS_FAKEDIST;

pIterate = m_hSources;

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if ( !pPlayer )

return NULL;

pPlayer->EyeVectors( &vecLOS );

while( *pIterate )

{

flTestDist = GetSoundDist( *pIterate, vecLOS );

if( flTestDist < flBestSoundDist )

{

flBestSoundDist = flTestDist;

pBestSound = *pIterate;

}

pIterate++;

}

return pBestSound;

}

//-----------------------------------------------------------------------------

// Purpose: Overloaded to handle the zoom functionality.

//-----------------------------------------------------------------------------

void CWeaponBinoculars::ItemPostFrame( void )

{

// This should really be PREFRAME.

if( gpGlobals->curtime >= m_NextCacheTime && m_nZoomLevel != 0 )

{

CacheSoundSources();

}

CBaseEntity *pSound;

pSound = LocateBestSound();

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if (pPlayer == NULL)

{

return;

}

float flStaticVolume;

float flSignalVolume;

float flDot;

if( m_nZoomLevel != 0 )

{

Vector vecToSound;

Vector vecFacing;

pPlayer->EyeVectors( &vecFacing );

if( pSound )

{

// Trying to tune a sound in.

vecToSound = pSound->GetLocalOrigin() - pPlayer->GetLocalOrigin();

VectorNormalize( vecToSound );

flDot = DotProduct( vecToSound, vecFacing );

/*

// FIXME: Disabled this, the code for doing this must exist on the client

if( flDot > 0.95 )

{

engine->EnableHOrigin( true );

engine->SetHOrigin( pSound->GetLocalOrigin() );

}

else

{

engine->EnableHOrigin( false );

}

*/

// static volume gets louder the farther you are from sound

// signal volume gets louder as you near sound.

flStaticVolume = ( 1.0 - flDot ) * 2.0;

// signal volume gets louder as you near, quieter as you get VERY near.

if( flDot < 0.90 || flDot > 0.9995 )

{

flSignalVolume = 0.1;

}

else

{

//flSignalVolume = (flDot - 0.6) * 2;

flSignalVolume = flDot;

}

}

else

{

// No sound. Static.

flSignalVolume = 0.0;

flStaticVolume = 1.0;

//engine->EnableHOrigin( false );

}

#if 0

Msg( "Dot:%f - Static:%f - Signal:%f\n", flDot, flStaticVolume, flSignalVolume );

#endif

}

else

{

flStaticVolume = flSignalVolume = 0.0;

//engine->EnableHOrigin( false );

}

CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();

controller.SoundChangeVolume( m_pSoundStatic, flStaticVolume, 0.1 );

controller.SoundChangeVolume( m_pSoundSignal, flSignalVolume, 0.1 );

if ( pPlayer->m_nButtons & IN_ATTACK )

{

if ( m_fNextZoom <= gpGlobals->curtime )

{

Zoom( Zoom_In );

pPlayer->m_nButtons &= ~IN_ATTACK;

}

}

else if ( pPlayer->m_nButtons & IN_ATTACK2 )

{

if ( m_fNextZoom <= gpGlobals->curtime )

{

Zoom( Zoom_Out );

pPlayer->m_nButtons &= ~IN_ATTACK2;

}

}

//

// No buttons down.

//

if (!(( pPlayer->m_nButtons & IN_ATTACK ) || ( pPlayer->m_nButtons & IN_ATTACK2 )))

{

WeaponIdle();

return;

}

}

//-----------------------------------------------------------------------------

// Purpose:

//-----------------------------------------------------------------------------

void CWeaponBinoculars::Precache( void )

{

PrecacheSound( "weapons/binoculars/buzz.wav" );

PrecacheSound( "weapons/binoculars/signal.wav" );

BaseClass::Precache();

}

//-----------------------------------------------------------------------------

// Purpose: Zooms in using the sniper rifle scope.

//-----------------------------------------------------------------------------

void CWeaponBinoculars::Zoom( ZoomMode_t eMode )

{

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if ( !pPlayer )

{

return;

}

switch ( eMode )

{

//

// Stop zooming with the binoculars.

//

case Zoom_Exit:

{

if ( m_nZoomLevel != 0 )

{

pPlayer->ShowViewModel(true);

WeaponSound( SPECIAL2 );

pPlayer->SetFOV( this, 0 );

m_nZoomLevel = 0;

}

break;

}

//

// Zoom in.

//

case Zoom_In:

{

if (( m_nZoomLevel + 1 ) < ( sizeof( g_nZoomFOV ) / sizeof( g_nZoomFOV[0] )))

{

m_nZoomLevel++;

WeaponSound( SPECIAL1 );

pPlayer->SetFOV( this, g_nZoomFOV[m_nZoomLevel] );

if (g_nZoomFOV[m_nZoomLevel] != 0)

{

pPlayer->ShowViewModel(false);

}

}

else

{

// Can't zoom in any further; play a special sound.

WeaponSound( RELOAD );

}

m_fNextZoom = gpGlobals->curtime + BINOCULARS_ZOOM_RATE;

break;

}

//

// Zoom out.

//

case Zoom_Out:

{

if ( m_nZoomLevel > 0 )

{

m_nZoomLevel--;

WeaponSound( SPECIAL2 );

pPlayer->SetFOV( this, g_nZoomFOV[m_nZoomLevel] );

if ( g_nZoomFOV[m_nZoomLevel] == 0 )

{

pPlayer->ShowViewModel(true);

}

}

m_fNextZoom = gpGlobals->curtime + BINOCULARS_ZOOM_RATE;

break;

}

default:

{

break;

}

}

}

После этого мы идём в клиентовскую часть. Идём сюда (src\cl_dll\hl2_hud\c_weapon__stubs_hl2.cpp) и вписываем где то после:

STUB_WEAPON_CLASS( weapon_bugbait, WeaponBugBait, C_BaseHLCombatWeapon );

Вот это:

STUB_WEAPON_CLASS( weapon_binoculars, WeaponBinoculars, C_BaseHLCombatWeapon );

Всё, в клиете всё сделано. Теперь нам надо сделать такую штуку что б при импульс 101 нам довалось всё оружие, включая наш бинокль Так что направляемся сюда (src\dlls\player.cpp) и ищем в этом файле строку case 101 и чуть ниже вы найдете строки куда вписывать оружие, не путаете с тем где вписывать патроны, так что где то после:

GiveNamedItem( "weapon_crossbow" );

Вот эту строку:

GiveNamedItem( "weapon_binoculars"

Но это еще не всё, надо кое-что поправить в файлике baseentity (src\dlls\baseentity.h) в нем ищем такую строку:

// Returns a CBaseAnimating if the entity is derived from CBaseAnimating.

И перед ней сразу пишем:

virtual bool IsSoundSource( void ) { return false; };

Всё, можно компилить! Но надо теперь сделать скрипт для этой пушки, так что неторопимся запускать игру Теперь лезем в вашу папку с модом, а оттуда в папку Scripts и там создадим файлик weapon_binoculars.txt куда впишем следующие:

//Binoculars

WeaponData

{

// Weapon data is loaded by both the Game and Client DLLs.

"printname" "Binoculars"

"viewmodel" "models/weapons/v_binoculars.mdl"

"playermodel" "models/weapons/w_binoculars.mdl"

"anim_prefix" "binoculars"

"bucket" "3"

"bucket_position" "3"

"clip_size" "-1"

"primary_ammo" "None"

"secondary_ammo" "None"

"weight" "0"

"item_flags" "0"

// Sounds for the weapon. There is a max of 16 sounds per category (i.e. max 16 "single_shot" sounds)

SoundData

{

"special1" "Weapon_Binoculars.Special1"

"special2" "Weapon_Binoculars.Special2"

"reload" "Weapon_Binoculars.Reload"

}

// Weapon Sprite data is loaded by the Client DLL.

TextureData

{

"weapon"

{

"file" "sprites/w_icons1b"

"x" "1"

"y" "129"

"width" "126"

"height" "62"

}

"weapon_s"

{

"file" "sprites/w_icons1b"

"x" "1"

"y" "129"

"width" "126"

"height" "62"

}

"ammo"

{

"file" "sprites/640hud7"

"x" "0"

"y" "72"

"width" "24"

"height" "24"

}

"ammo2"

{

"file" "sprites/640hud7"

"x" "48"

"y" "72"

"width" "24"

"height" "24"

}

"crosshair"

{

"font" "Crosshairs"

"character" "Q"

}

"autoaim"

{

"file" "sprites/crosshairs"

"x" "48"

"y" "72"

"width" "24"

"height" "24"

}

"zoom"

{

"file" "sprites/reticle"

"x" "0"

"y" "0"

"width" "128"

"height" "128"

}

"zoom_autoaim"

{

"file" "sprites/reticle"

"x" "0"

"y" "0"

"width" "128"

"height" "128"

}

}

}

Сделали? Отлично! Вы уже думайте запускать игру? А нифига, надо сделать еще что б у нашей пушки были звуки, для этого лезем в scripts\game_sounds_weapons.txt и там где то после обозначений звуков арбалета впишем это:

// weapon_binoculars.txt

"Weapon_Binoculars.Special1"

{

"channel" "CHAN_WEAPON"

"volume" "1.0"

"soundlevel" "SNDLVL_NORM"

"wave" "weapons/binoculars/binoculars_zoomin.wav"

}

"Weapon_Binoculars.Special2"

{

"channel" "CHAN_WEAPON"

"volume" "1.0"

"soundlevel" "SNDLVL_NORM"

"wave" "weapons/binoculars/binoculars_zoomout.wav"

}

"Weapon_Binoculars.Reload"

{

"channel" "CHAN_ITEM"

"volume" "1.0"

"soundlevel" "SNDLVL_NORM"

"wave" "weapons/binoculars/binoculars_zoommax.wav"

}

Категория: Туториалы по программированию (HL2) | Автор: DetLeR (15.09.2007)

Категория: Программирование | Добавил: HellMapper (28.05.2009)
Просмотров: 795 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Имя *:
Email *:
Код *:
Форма входа

Группа Steam

Наша кнопка

Поиск

Друзья сайта


  • Официальный блог


  • YIIbIpu-TEAM


  • DETLER-TEAM



  • Copyright WEDGe © 2024