User:Psycommando/devolver source

From Valve Developer Community
< User:Psycommando
Revision as of 18:35, 23 April 2009 by Psycommando (talk | contribs) (Server code)

Jump to: navigation, 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.

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.