User:Psycommando/devolver source

From Valve Developer Community
Jump to navigation Jump to search

Intro

This is the source for a very quick modification of the 357 magnum to "shoot" laser beams( technically it only draws a laser beam while it still fire a bullet ). It really needs some polishing.

Do whatever you want with this code no need to credit or anything, most of it is from valve anyways. And it need a massive clean up! Lots of uselesss stuff in there!

Source code

Client code

This code goes in the ../src/game/client/ directory.

/*
c_weapon_devolver.cpp
18/04/2009
Psy_Commando, psycommando at gmail.com
Description : Client class of the devolver
*/
#include "cbase.h"
#include "c_weapon__stubs.h" //this include should be removed its useless
#include "basehlcombatweapon_shared.h"
#include "c_basehlcombatweapon.h"

//STUB_WEAPON_CLASS( weapon_devolver, WeaponDevolver, C_BaseHLCombatWeapon );

class C_WeaponDevolver: public C_BaseHLCombatWeapon
{
	DECLARE_CLASS( C_WeaponDevolver, C_BaseHLCombatWeapon );
public:
	C_WeaponDevolver();

	DECLARE_CLIENTCLASS();
	DECLARE_PREDICTABLE();

	//virtual void OnDataChanged( DataUpdateType_t updateType );
	//virtual int DrawModel( int flags );
	virtual void ClientThink();

private:

	//bool	SetupEmitter( void );

	//bool	m_bIsCurrentlyUpgrading;
	//float	m_flTimeForceView;
	//float	m_flTimeIgnoreForceView;
	//bool	m_bWasUpgraded;

	//CSmartPtr<CLocalSpaceEmitter>	m_pLocalEmitter;
	//CSmartPtr<CSimpleEmitter>		m_pEmitter;
	//CSmartPtr<CParticleAttractor>	m_pAttractor;
};

STUB_WEAPON_CLASS_IMPLEMENT( weapon_devolver, C_WeaponDevolver );

IMPLEMENT_CLIENTCLASS_DT( C_WeaponDevolver, DT_WeaponDevolver, CWeaponDevolver )
END_RECV_TABLE()


C_WeaponDevolver::C_WeaponDevolver()
{
}

void C_WeaponDevolver::ClientThink()
{
}

Server code

This code goes in the ../src/game/server/ directory.

/*
weapon_devolver.cpp
18/04/2009
Psy_Commando, psycommando at gmail.com
Description : Copy of valve's 357 magnum, turned into the devolver
*/

#include "cbase.h"
#include "NPCEvent.h"
#include "basehlcombatweapon.h"
#include "basecombatcharacter.h"
#include "AI_BaseNPC.h"
#include "player.h"
#include "gamerules.h"
#include "in_buttons.h"
#include "soundent.h"
#include "game.h"
#include "vstdlib/random.h"
#include "engine/IEngineSound.h"
#include "IEffects.h"
#include "beam_shared.h"
#include "te_effect_dispatch.h"
#include "gamestats.h"
#include "util.h"

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

//-----------------------------------------------------------------------------
// CWeaponDevolver
//-----------------------------------------------------------------------------

class CWeaponDevolver : public CBaseHLCombatWeapon
{
	DECLARE_CLASS( CWeaponDevolver, CBaseHLCombatWeapon );
public:

	CWeaponDevolver( void );
    void Precache();

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

	float	WeaponAutoAimScale()	{ return 0.6f; }

	DECLARE_SERVERCLASS();
	DECLARE_DATADESC();
};

LINK_ENTITY_TO_CLASS( weapon_devolver, CWeaponDevolver );

PRECACHE_WEAPON_REGISTER( weapon_devolver );

IMPLEMENT_SERVERCLASS_ST( CWeaponDevolver, DT_WeaponDevolver )
END_SEND_TABLE()

BEGIN_DATADESC( CWeaponDevolver )
END_DATADESC()

//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeaponDevolver::CWeaponDevolver( void )
{
	m_bReloadsSingly	= false;
	m_bFiresUnderwater	= false;
}

void CWeaponDevolver::Precache()
{
    PrecacheModel( "sprites/laserbeam.vmt" );
    BaseClass::Precache();
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponDevolver::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

	switch( pEvent->event )
	{
		case EVENT_WEAPON_RELOAD:
			{
				CEffectData data;

				// Emit six spent shells
				for ( int i = 0; i < 6; i++ )
				{
					data.m_vOrigin = pOwner->WorldSpaceCenter() + RandomVector( -4, 4 );
					data.m_vAngles = QAngle( 90, random->RandomInt( 0, 360 ), 0 );
					data.m_nEntIndex = entindex();

					DispatchEffect( "ShellEject", data );
				}

				break;
			}
	}
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponDevolver::PrimaryAttack( void )
{
	// Only the player fires this way so we can cast
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	if ( !pPlayer )
	{
		return;
	}

	if ( m_iClip1 <= 0 )
	{
		if ( !m_bFireOnEmpty )
		{
			Reload();
		}
		else
		{
			WeaponSound( EMPTY );
			m_flNextPrimaryAttack = 0.15;
		}

		return;
	}

	m_iPrimaryAttacks++;
	gamestats->Event_WeaponFired( pPlayer, true, GetClassname() );

    //play the sound from the weapon script
	WeaponSound( SINGLE );
	pPlayer->DoMuzzleFlash();

    //Animate model
	SendWeaponAnim( ACT_VM_PRIMARYATTACK );
	pPlayer->SetAnimation( PLAYER_ATTACK1 );

    // Set delay between shots
	m_flNextPrimaryAttack = gpGlobals->curtime + 0.35;
	m_flNextSecondaryAttack = gpGlobals->curtime + 0.35;

	m_iClip1--;

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

	//*************************************
	// Beam code starts here
	//*************************************
        //#pyscommando : this stuff should go in its own function.

    trace_t	tr;
	UTIL_TraceLine( vecSrc, vecSrc + (vecAiming * MAX_TRACE_LENGTH), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );

    //Draw the main beam shaft
	CBeam *pBeam = CBeam::BeamCreate( "sprites/laserbeam.vmt", 0.5 );
	
    //#psycommando: This code is confusing because it traces the beam the wrong way : the end is the beginning 
    //              and the beginning is the end.
    pBeam->SetEndAttachment( 1 ); //#psycommando: This is stupid because it actually sets the starting attachment of the beam, instead of setting the real end.
    pBeam->PointEntInit( tr.endpos, pPlayer->GetActiveWeapon() ); //Beam Init for a point to an entity 
    pBeam->SetEndAttachment( 1 ); //Sets muzzle attachment
    pBeam->LiveForTime( 0.1f );
    pBeam->SetNoise( 0.1f ); //noise of the beam, the more noise the more zig-zag it will do.
    pBeam->SetBeamFlags( SF_BEAM_STARTON | SF_BEAM_TEMPORARY );
    pBeam->SetWidth( 5.0f );
    pBeam->SetEndWidth( 0.1f );
    pBeam->SetBrightness( 255 );
    pBeam->SetColor( 255, 50+random->RandomInt( -16, 16 ), 0 ); //color of the beam in RGB format.
    pBeam->RelinkBeam(); //force the recalculation of the beam I guess

    Vector	shotDir = ( tr.endpos - pPlayer->Weapon_ShootPosition() );
	VectorNormalize( shotDir );

    CPVSFilter filter( tr.endpos );
	te->GaussExplosion( filter, 0.0f, tr.endpos - ( shotDir * 4.0f ), RandomVector(-1.0f, 1.0f), 0 );
	
	//*************************************
	// Beam code ends here
	//*************************************

	pPlayer->FireBullets( 1, vecSrc, vecAiming, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );

	pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );

	//Disorient the player
	QAngle angles = pPlayer->GetLocalAngles();

	angles.x += random->RandomInt( -1, 1 );
	angles.y += random->RandomInt( -1, 1 );
	angles.z = 0;

	pPlayer->SnapEyeAngles( angles );

    //Camera shake
	pPlayer->ViewPunch( QAngle( -8, random->RandomFloat( -2, 2 ), 0 ) );

    //Ai sound warning
	CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.2, GetOwner() );

	if ( !m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
	{
		// HEV suit - indicate out of ammo condition
		//pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); 
        //#psycommando : I'd rather send a message to the main hud
	}
}

Weapon script

This goes in your mod's script directory, create a txt file named weapon_devolver.txt.

// devolver

WeaponData
{
	// Weapon data is loaded by both the Game and Client DLLs.
	"printname"			"Devolver"
	"viewmodel"			"models/weapons/v_357.mdl"
	"playermodel"		"models/weapons/w_357.mdl"
	"anim_prefix"		"python"
	"bucket"			"1"
	"bucket_position"	"1"

	"clip_size"			"150"
	"default_clip"		"150"
	"primary_ammo"		"357"
	"secondary_ammo"	"None"

	"weight"		"7"
	"item_flags"		"0"

	// Sounds for the weapon. There is a max of 16 sounds per category (i.e. max 16 "single_shot" sounds)
	SoundData
	{
		"empty"		"Weapon_Pistol.Empty"
		"single_shot"	"Weapon_357.Single"
	}

	// Weapon Sprite data is loaded by the Client DLL.
	TextureData
	{
		"weapon"
		{
				"font"		"WeaponIcons"
				"character"	"e"
		}
		"weapon_s"
		{	
				"font"		"WeaponIconsSelected"
				"character"	"e"
		}
		"ammo"
		{
				"font"		"WeaponIcons"
				"character"	"q"
		}
		"crosshair"
		{
				"font"		"Crosshairs"
				"character"	"Q"
		}
		"autoaim"
		{
				"file"		"sprites/crosshairs"
				"x"			"0"
				"y"			"48"
				"width"		"24"
				"height"	"24"
		}
	}
}

How to get the weapon ingame

Just type give weapon_devolver in the console.

I hope this was useful.