Понедельник, 07.10.2024, 02:03
 
Приветствую Вас Guest | RSS
Главная страница | Лазер для веапона - Форум | Регистрация | Вход
[Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Лазер для веапона
kostyl_headcrabДата: Суббота, 02.10.2010, 13:59 | Сообщение # 1
Engineer
Группа: Проверенные
Сообщений: 76
Репутация: 2
Статус: Offline
Короче, решил я приделать лазер к снайперке из беты. Код потырел из funk_tank (Combine Ion Cannon), а чтобы правильно оформить смотрел в grenade_tripmine.h и grenade_tripmine.cpp. Откомпилил без ошибок, но сам лазер не видно в игре. Вот код, который у меня получился (Напишу весь код, отдельные куски которые я добавил или изменил, писать не буду):

Code
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Implements a sniper rifle weapon.
//     
//   Primary attack: fires a single high-powered shot, then reloads.
//   Secondary attack: cycles sniper scope through zoom levels.
//
// TODO: Circular mask around crosshairs when zoomed in.
// TODO: Shell ejection.
// TODO: Finalize kickback.
// TODO: Animated zoom effect?
//
//=============================================================================//

#include "cbase.h"
#include "beam_shared.h"
#include "NPCEvent.h"
#include "basehlcombatweapon.h"
#include "basecombatcharacter.h"
#include "AI_BaseNPC.h"
#include "player.h"
#include "gamerules.h"    // For g_pGameRules
#include "in_buttons.h"
#include "soundent.h"
#include "vstdlib/random.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

#define SNIPER_CONE_PLAYER     vec3_origin    // Spread cone when fired by the player.
#define SNIPER_CONE_NPC      vec3_origin    // Spread cone when fired by NPCs.
#define SNIPER_BULLET_COUNT_PLAYER   1   // Fire n bullets per shot fired by the player.
#define SNIPER_BULLET_COUNT_NPC    1   // Fire n bullets per shot fired by NPCs.
#define SNIPER_TRACER_FREQUENCY_PLAYER  0   // Draw a tracer every nth shot fired by the player.
#define SNIPER_TRACER_FREQUENCY_NPC   0   // Draw a tracer every nth shot fired by NPCs.
#define SNIPER_KICKBACK      3   // Range for punchangle when firing.

#define SNIPER_ZOOM_RATE     0.2   // Interval between zoom levels in seconds.
#define SNIPER_BEAM "effects/blueblacklargebeam.vmt"

//-----------------------------------------------------------------------------
// Discrete zoom levels for the scope.
//-----------------------------------------------------------------------------
static int g_nZoomFOV[] =
{
   20,
   5
};

class CBeam;

class CWeaponSniperRifle : public CBaseHLCombatWeapon
{
   DECLARE_DATADESC();
public:
   DECLARE_CLASS( CWeaponSniperRifle, CBaseHLCombatWeapon );

   CWeaponSniperRifle(void);

   DECLARE_SERVERCLASS();

   void Precache( void );

   int CapabilitiesGet( void ) const;

   const Vector &GetBulletSpread( void );

   bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
   void ItemPostFrame( void );
   void PrimaryAttack( void );
   bool Reload( void );
   void Zoom( void );
   void CreateBeam();
   virtual float GetFireRate( void ) { return 1; };

   void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );

   DECLARE_ACTTABLE();

private:
   CBeam  *m_hBeam;

protected:

   float m_fNextZoom;
   int m_nZoomLevel;
};

IMPLEMENT_SERVERCLASS_ST(CWeaponSniperRifle, DT_WeaponSniperRifle)
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( weapon_sniperrifle, CWeaponSniperRifle );
PRECACHE_WEAPON_REGISTER(weapon_sniperrifle);

BEGIN_DATADESC( CWeaponSniperRifle )

   DEFINE_FIELD( m_fNextZoom, FIELD_FLOAT ),
   DEFINE_FIELD( m_nZoomLevel, FIELD_INTEGER ),
   DEFINE_FIELD( m_hBeam, FIELD_EHANDLE ),

END_DATADESC()

//-----------------------------------------------------------------------------
// Maps base activities to weapons-specific ones so our characters do the right things.
//-----------------------------------------------------------------------------
acttable_t    CWeaponSniperRifle::m_acttable[] =   
{
   {    ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SNIPER_RIFLE, true }
};

IMPLEMENT_ACTTABLE(CWeaponSniperRifle);

//-----------------------------------------------------------------------------
// Purpose: Constructor.
//-----------------------------------------------------------------------------
CWeaponSniperRifle::CWeaponSniperRifle( void )
{
   m_fNextZoom = gpGlobals->curtime;
   m_nZoomLevel = 0;

   m_bReloadsSingly = true;

   m_fMinRange1  = 65;
   m_fMinRange2  = 65;
   m_fMaxRange1  = 2048;
   m_fMaxRange2  = 2048;
}

//-----------------------------------------------------------------------------
// Purpose:   
// Output : int
//-----------------------------------------------------------------------------
int CWeaponSniperRifle::CapabilitiesGet( void ) const
{
   return bits_CAP_WEAPON_RANGE_ATTACK1;
}

//-----------------------------------------------------------------------------
// Purpose: Turns off the zoom when the rifle is holstered.
//-----------------------------------------------------------------------------
bool CWeaponSniperRifle::Holster( CBaseCombatWeapon *pSwitchingTo )
{
   CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
   if (pPlayer != NULL)
   {
    if ( m_nZoomLevel != 0 )
    {
     if ( pPlayer->SetFOV( this, 0 ) )
     {
      pPlayer->ShowViewModel(true);    
      m_nZoomLevel = 0;
     }
    }
   }

   return BaseClass::Holster(pSwitchingTo);
}

//-----------------------------------------------------------------------------
// Purpose: Overloaded to handle the zoom functionality.
//-----------------------------------------------------------------------------
void CWeaponSniperRifle::ItemPostFrame( void )
{
   CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
   if (pPlayer == NULL)
   {
    return;
   }

   if ((m_bInReload) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
   {
    FinishReload();
    m_bInReload = false;
   }

   if (pPlayer->m_nButtons & IN_ATTACK2)
   {
    if (m_fNextZoom <= gpGlobals->curtime)
    {
     Zoom();
     pPlayer->m_nButtons &= ~IN_ATTACK2;
    }
   }
   else if ((pPlayer->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
   {
    if ( (m_iClip1 == 0 && UsesClipsForAmmo1()) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) )
    {
     m_bFireOnEmpty = true;
    }

    // Fire underwater?
    if (pPlayer->GetWaterLevel() == 3 && m_bFiresUnderwater == false)
    {
     WeaponSound(EMPTY);
     m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
     return;
    }
    else
    {
     // If the firing button was just pressed, reset the firing time
     if ( pPlayer && pPlayer->m_afButtonPressed & IN_ATTACK )
     {
       m_flNextPrimaryAttack = gpGlobals->curtime;
     }

     PrimaryAttack();
    }
   }

   // -----------------------
   //  Reload pressed / Clip Empty
   // -----------------------
   if ( pPlayer->m_nButtons & IN_RELOAD && UsesClipsForAmmo1() && !m_bInReload )   
   {
    // reload when reload is pressed, or if no buttons are down and weapon is empty.
    Reload();
   }

   // -----------------------
   //  No buttons down
   // -----------------------
   if (!((pPlayer->m_nButtons & IN_ATTACK) || (pPlayer->m_nButtons & IN_ATTACK2) || (pPlayer->m_nButtons & IN_RELOAD)))
   {
    // no fire buttons down
    m_bFireOnEmpty = false;

    if ( !HasAnyAmmo() && m_flNextPrimaryAttack < gpGlobals->curtime )   
    {
     // weapon isn't useable, switch.
     if ( !(GetWeaponFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && pPlayer->SwitchToNextBestWeapon( this ) )
     {
      m_flNextPrimaryAttack = gpGlobals->curtime + 0.3;
      return;
     }
    }
    else
    {
     // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
     if ( m_iClip1 == 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime )
     {
      Reload();
      return;
     }
    }

    WeaponIdle( );
    return;
   }
}

//-----------------------------------------------------------------------------
// Purpose:   
//-----------------------------------------------------------------------------
void CWeaponSniperRifle::Precache( void )
{
   BaseClass::Precache();
   PrecacheModel(SNIPER_BEAM);
}

//-----------------------------------------------------------------------------
// Purpose: Same as base reload but doesn't change the owner's next attack time. This
//   lets us zoom out while reloading. This hack is necessary because our
//   ItemPostFrame is only called when the owner's next attack time has
//   expired.
// Output : Returns true if the weapon was reloaded, false if no more ammo.
//-----------------------------------------------------------------------------
bool CWeaponSniperRifle::Reload( void )
{
   CBaseCombatCharacter *pOwner = GetOwner();
   if (!pOwner)
   {
    return false;
   }
      
   if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) > 0)
   {
    int primary  = min(GetMaxClip1() - m_iClip1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));
    int secondary    = min(GetMaxClip2() - m_iClip2, pOwner->GetAmmoCount(m_iSecondaryAmmoType));

    if (primary > 0 || secondary > 0)
    {
     CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if (!pPlayer)
{
   return false;
}
if ( pPlayer->SetFOV( this, 0 ) )
{
   pPlayer->ShowViewModel(true);
   m_nZoomLevel = 0;
}
     // Play reload on different channel as it happens after every fire
     // and otherwise steals channel away from fire sound
     WeaponSound(RELOAD);
     SendWeaponAnim( ACT_VM_RELOAD );
     m_fNextZoom = gpGlobals->curtime + SequenceDuration();

     m_flNextPrimaryAttack    = gpGlobals->curtime + SequenceDuration();

     m_bInReload = true;
    }

    return true;
   }

   return false;
}

//-----------------------------------------------------------------------------
// Purpose:   
//-----------------------------------------------------------------------------
void CWeaponSniperRifle::PrimaryAttack( void )
{
   // Only the player fires this way so we can cast safely.
   CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
   if (!pPlayer)
   {
    return;
   }

   if ( gpGlobals->curtime >= m_flNextPrimaryAttack )
   {
    // If my clip is empty (and I use clips) start reload
    if ( !m_iClip1 )   
    {
     Reload();
     return;
    }

    // MUST call sound before removing a round from the clip of a CMachineGun dvs: does this apply to the sniper rifle? I don't know.
    WeaponSound(SINGLE);

    pPlayer->DoMuzzleFlash();

    SendWeaponAnim( ACT_VM_PRIMARYATTACK );

    // player "shoot" animation
    pPlayer->SetAnimation( PLAYER_ATTACK1 );

    // Don't fire again until fire animation has completed
    m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
    m_iClip1 = m_iClip1 - 1;

    Vector vecSrc  = pPlayer->Weapon_ShootPosition();
    Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );   

    // Fire the bullets
    pPlayer->FireBullets( SNIPER_BULLET_COUNT_PLAYER, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, SNIPER_TRACER_FREQUENCY_PLAYER );

    CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.2 );

    QAngle vecPunch(random->RandomFloat( -SNIPER_KICKBACK, SNIPER_KICKBACK ), 0, 0);
    pPlayer->ViewPunch(vecPunch);

    // Indicate out of ammo condition if we run out of ammo.
    if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
    {
     pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);   
    }
   }

   // Register a muzzleflash for the AI.
   pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );
}

void CWeaponSniperRifle::CreateBeam()
{
     m_hBeam = CBeam::BeamCreate( SNIPER_BEAM, 1.0f );
        m_hBeam->SetColor( 255, 255, 255 );

               m_hBeam->SetBrightness( 255 );
               m_hBeam->SetNoise( 0 );
               m_hBeam->SetWidth( 3.0f );
               m_hBeam->SetEndWidth( 0 );
               m_hBeam->SetScrollRate( 0 );
               m_hBeam->SetFadeLength( 60 );
               m_hBeam->SetHaloScale( 4.0f );
}

//-----------------------------------------------------------------------------
// Purpose: Zooms in using the sniper rifle scope.
//-----------------------------------------------------------------------------
void CWeaponSniperRifle::Zoom( void )
{
   CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
   if (!pPlayer)
   {
    return;
   }

   if (m_nZoomLevel >= sizeof(g_nZoomFOV) / sizeof(g_nZoomFOV[0]))
   {
    if ( pPlayer->SetFOV( this, 0 ) )
    {
     pPlayer->ShowViewModel(true);
       
     // Zoom out to the default zoom level
     WeaponSound(SPECIAL2);   
     m_nZoomLevel = 0;
    }
   }
   else
   {
    if ( pPlayer->SetFOV( this, g_nZoomFOV[m_nZoomLevel] ) )
    {
     if (m_nZoomLevel == 0)
     {
      pPlayer->ShowViewModel(false);
     }

     WeaponSound(SPECIAL1);
       
     m_nZoomLevel++;
    }
   }

   m_fNextZoom = gpGlobals->curtime + SNIPER_ZOOM_RATE;
}

//-----------------------------------------------------------------------------
// Purpose:   
// Output : virtual const Vector&
//-----------------------------------------------------------------------------
const Vector &CWeaponSniperRifle::GetBulletSpread( void )
{
   static Vector cone = SNIPER_CONE_PLAYER;
   return cone;
}

//-----------------------------------------------------------------------------
// Purpose:   
// Input  : *pEvent -   
//   *pOperator -   
//-----------------------------------------------------------------------------
void CWeaponSniperRifle::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
   switch ( pEvent->event )
   {
    case EVENT_WEAPON_SNIPER_RIFLE_FIRE:
    {
     Vector vecShootOrigin, vecShootDir;
     vecShootOrigin = pOperator->Weapon_ShootPosition();

     CAI_BaseNPC *npc = pOperator->MyNPCPointer();
     Vector vecSpread;
     if (npc)
     {
      vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin );
      vecSpread = VECTOR_CONE_PRECALCULATED;
     }
     else
     {
      AngleVectors( pOperator->GetLocalAngles(), &vecShootDir );
      vecSpread = GetBulletSpread();
     }
     WeaponSound( SINGLE_NPC );
     pOperator->FireBullets( SNIPER_BULLET_COUNT_NPC, vecShootOrigin, vecShootDir, vecSpread, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, SNIPER_TRACER_FREQUENCY_NPC );
     pOperator->DoMuzzleFlash();
     break;
    }

    default:
    {
     BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
     break;
    }
   }
}


Было отредактированно - kostyl_headcrab - Суббота, 02.10.2010, 14:00
 
AndreazzzДата: Суббота, 02.10.2010, 18:55 | Сообщение # 2
Spy
Группа: Проверенные
Сообщений: 996
Репутация: 55
Статус: Offline
kostyl_headcrab, ты напиши куски, ты в коде гденибудь функцию CreateBeam использовал

Добавлено (02.10.2010, 18:55)
---------------------------------------------
И ещё скинь сюда код потестить


 
kostyl_headcrabДата: Воскресенье, 03.10.2010, 03:45 | Сообщение # 3
Engineer
Группа: Проверенные
Сообщений: 76
Репутация: 2
Статус: Offline
Andreazzz, куски:

Code
#include "beam_shared.h"

#define SNIPER_BEAM "effects/blueblacklargebeam.vmt"

class CBeam;

void CreateBeam();

private:
CBeam *m_hBeam;

DEFINE_FIELD( m_hBeam, FIELD_EHANDLE ),

PrecacheModel(SNIPER_BEAM);

void CWeaponSniperRifle::CreateBeam()
{
m_hBeam = CBeam::BeamCreate( SNIPER_BEAM, 1.0f );
m_hBeam->SetColor( 255, 255, 255 );

m_hBeam->SetBrightness( 255 );
m_hBeam->SetNoise( 0 );
m_hBeam->SetWidth( 3.0f );
m_hBeam->SetEndWidth( 0 );
m_hBeam->SetScrollRate( 0 );
m_hBeam->SetFadeLength( 60 );
m_hBeam->SetHaloScale( 4.0f );
}

Добавлено (03.10.2010, 03:45)
---------------------------------------------
Andreazzz, добавь снайперку по тутору, а потом в weapon_sniperrifle.cpp впиши код из первого сообщения.

Было отредактированно - kostyl_headcrab - Воскресенье, 03.10.2010, 03:42
 
AndreazzzДата: Воскресенье, 03.10.2010, 10:35 | Сообщение # 4
Spy
Группа: Проверенные
Сообщений: 996
Репутация: 55
Статус: Offline
kostyl_headcrab, ты незаюзал CreateBeam, и вобще, откуда ты брал этот код?

Добавлено (03.10.2010, 10:30)
---------------------------------------------
В grenade_tripmine эта функция используется в Think (думай, и смотри RPG за подсказкой biggrin )

Добавлено (03.10.2010, 10:35)
---------------------------------------------
kostyl_headcrab, проще выдерай код из RPG


 
kostyl_headcrabДата: Воскресенье, 03.10.2010, 10:36 | Сообщение # 5
Engineer
Группа: Проверенные
Сообщений: 76
Репутация: 2
Статус: Offline
Andreazzz, код брал из исходников, которые ты мне скинул. Я имею в виду исходники EP2. Файл func_tank.cpp. Почти в самом низу файла написан код комбайновской ионной пушки. Оттуда и взял код.
 
  • Страница 1 из 1
  • 1
Поиск:

Помощь в разработке форума: HOMiE7