Adding new weapon / Making weapon Dualies

  • Thread starter Thread starter Duckman
  • Start date Start date
D

Duckman

Guest
Hello everyone,

I am new to coding with the Source Engine and I was looking to add
dual magnums and I have done all of the steps in the tutorial for it
and added a weapon_Dualies357.txt to the scripts folder, and also
added it to the list of items added with impulse 101 and it still
doesnt seem to show up, i want it to come up under the regular magnum
here is the .txt info:

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

       "clip_size"                     "6"
       "default_clip"          "6"
       "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"     "d"
               }
               "weapon_s"
               {
                               "font"          "WeaponIconsSelected"
                               "character"     "d"
               }
               "ammo"
               {
                               "font"          "WeaponIcons"
                               "character"     "p"
               }
               "crosshair"
               {
                               "font"          "Crosshairs"
                               "character"     "Q"
               }
               "autoaim"
               {
                               "file"          "sprites/crosshairs"
                               "x"                     "0"
                               "y"                     "48"
                               "width"         "24"
                               "height"        "24"
               }
       }
}

Please if anyone can help on here that would be great, I tried on the hl2coders mailing list and came up with no answers.

Thanks,
Mike
 
usually this happens to me when I use a bucket that's already being used, try setting your bucket to something that's blank and seeing if it shows up


by the looks of your script, it seems like it's trying to replace one of the melee weapons...
 
what does it say in the console when you try to give it to yourself ?
try
give weapon_whatever
in the console . make sure you're in debugging mode.
 
First I want to say is thanks guy for responding. Ok now for the response, lol: to answer shinobi, i am just using the bucket position after the 357 magnum, i looked at pistol and 357.txts and they had the same bucket but position was 0 and 1 accordingly so i figured might as well go with 2, so im sure that isnt it, but i will def start fooling around with them if nothing else works. Now to answer mindless, I havent tried that yet and I will once i get back on again, but how do i run in debug mode, do i just compile the code in debugging compile mode then run from steam? I tried running from code and it would simply not work If you could help me out on that question that would be great.

Thanks guys again for responding and helping out,
Duckman
 
Attempted to create unknown entity type weapon_dualies357!
NULL Ent in GiveNamedItem!

Well that certaintly doesnt look like i did it correctly lol, i will look this up thanks guys
 
yeah i think something is wrong with the way you defined the class , are you sure that the class is linked to an entity name ? .
 
how do i link the weapon to an entity?

EDIT: I am guessing it is this line
Code:
LINK_ENTITY_TO_CLASS( weapon_Dualies357, CWeaponDualies357 );
?
 
yup thats it :) , also if its a single player mod you need to add the weapon to the client weapon stubs .
 
dude i cant win, i have that in there as well as
Code:
STUB_WEAPON_CLASS( weapon_Dualies357, WeaponDualies357, C_BaseHLCombatWeapon );
GAHHH!:sniper:
 
compile it again and check if your client.dll and server.dll in the bin of the game are created on the correct time and date, if not then thats ur problem. then try to look up the client.dll and server.dll in your source files (just search them) and place them there by hand.
 
o ok so you feel that they are not being ported over to the steam folder when i compile, and if not then just do the ol' copy and paste?
 
hmm i still think its a class issue , you're missing out on some small integral component. can you atleast see the weapon in hammer ? .
 
o ok so you feel that they are not being ported over to the steam folder when i compile, and if not then just do the ol' copy and paste?
yep exactly, sometimes your problem is quite easy I had this prob sometimes.
So check it and your certain of it that your compiled dll's are loaded, and you can look into the c++ files.
 
o ok so you feel that they are not being ported over to the steam folder when i compile, and if not then just do the ol' copy and paste?

thats definitely happened to me countless times, lol
 
thats odd :S , it really shouldnt happen if you set up your workspace properly.
 
ok checked the dlls they seem recent enough, now this could be a breakthrough, i dont see weapon_Dualies357 in my entities list in hammer, is that what you were referring to mindless?
 
btw if you want the gun to be given to you by the impulse 101 command then you have to add it to the list
under
CBasePlayer::CheatImpulseCommands

edit: that certainly isnt the issue here , just thought i should mention it.
 
yeah its there lol, um what do u think about it not being in hammer? like u asked before
 
it means that the entity got fudged up , i think you should redo it from scratch if it wasnt anything special OR post your files here .
 
ok i re did it and nothing... im gonna post code for all files related to this tutorial
weapon_dualies.cpp
Code:
//========= Copyright ? 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:		Dualies - hand gun
//
// $NoKeywords: $
//=============================================================================//

#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"

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

#define	DUALIES_FASTEST_REFIRE_TIME		0.1f
#define	DUALIES_FASTEST_DRY_REFIRE_TIME	0.2f

#define	DUALIES_ACCURACY_SHOT_PENALTY_TIME		0.2f	// Applied amount of time each shot adds to the time we must recover from
#define	DUALIES_ACCURACY_MAXIMUM_PENALTY_TIME	1.5f	// Maximum penalty to deal out

ConVar	dualies_use_new_accuracy( "dualies_use_new_accuracy", "1" );

//-----------------------------------------------------------------------------
// CWeaponDualies
//-----------------------------------------------------------------------------

class CWeaponDualies : public CBaseHLCombatWeapon
{
	DECLARE_DATADESC();

public:
	DECLARE_CLASS( CWeaponDualies, CBaseHLCombatWeapon );

	CWeaponDualies(void);

	DECLARE_SERVERCLASS();

	void	Precache( void );
	void	ItemPostFrame( void );
	void	ItemPreFrame( void );
	void	ItemBusyFrame( void );
	void	PrimaryAttack( void );
	void	AddViewKick( void );
	void	DryFire( void );
	void	PostFireStuff( void );
	void	Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );

	void	UpdatePenaltyTime( void );

	int		CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }
	Activity	GetPrimaryAttackActivity( void );

	virtual bool Reload( void );

	virtual const Vector& GetBulletSpread( void )
	{		
		// Handle NPCs first
		static Vector npcCone = VECTOR_CONE_5DEGREES;
		if ( GetOwner() && GetOwner()->IsNPC() )
			return npcCone;
			
		static Vector cone;

		if ( dualies_use_new_accuracy.GetBool() )
		{
			float ramp = RemapValClamped(	m_flAccuracyPenalty, 
											0.0f, 
											DUALIES_ACCURACY_MAXIMUM_PENALTY_TIME, 
											0.0f, 
											1.0f ); 

			// We lerp from very accurate to inaccurate over time
			VectorLerp( VECTOR_CONE_1DEGREES, VECTOR_CONE_6DEGREES, ramp, cone );
		}
		else
		{
			// Old value
			cone = VECTOR_CONE_4DEGREES;
		}

		return cone;
	}
	
	virtual int	GetMinBurst() 
	{ 
		return 1; 
	}

	virtual int	GetMaxBurst() 
	{ 
		return 3; 
	}

	virtual float GetFireRate( void ) 
	{
		return 0.5f; 
	}

	DECLARE_ACTTABLE();

private:
	float	m_flSoonestPrimaryAttack;
	float	m_flLastAttackTime;
	float	m_flAccuracyPenalty;
	int		m_nNumShotsFired;
	bool	Flip;
};


IMPLEMENT_SERVERCLASS_ST(CWeaponDualies, DT_WeaponDualies)
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( weapon_dualies, CWeaponDualies );
PRECACHE_WEAPON_REGISTER( weapon_dualies );

BEGIN_DATADESC( CWeaponDualies )

	DEFINE_FIELD( m_flSoonestPrimaryAttack, FIELD_TIME ),
	DEFINE_FIELD( m_flLastAttackTime,		FIELD_TIME ),
	DEFINE_FIELD( m_flAccuracyPenalty,		FIELD_FLOAT ), //NOTENOTE: This is NOT tracking game time
	DEFINE_FIELD( m_nNumShotsFired,			FIELD_INTEGER ),

END_DATADESC()

acttable_t	CWeaponDualies::m_acttable[] = 
{
	{ ACT_IDLE,						ACT_IDLE_PISTOL,				true },
	{ ACT_IDLE_ANGRY,				ACT_IDLE_ANGRY_PISTOL,			true },
	{ ACT_RANGE_ATTACK1,			ACT_RANGE_ATTACK_PISTOL,		true },
	{ ACT_RELOAD,					ACT_RELOAD_PISTOL,				true },
	{ ACT_WALK_AIM,					ACT_WALK_AIM_PISTOL,			true },
	{ ACT_RUN_AIM,					ACT_RUN_AIM_PISTOL,				true },
	{ ACT_GESTURE_RANGE_ATTACK1,	ACT_GESTURE_RANGE_ATTACK_PISTOL,true },
	{ ACT_RELOAD_LOW,				ACT_RELOAD_PISTOL_LOW,			false },
	{ ACT_RANGE_ATTACK1_LOW,		ACT_RANGE_ATTACK_PISTOL_LOW,	false },
	{ ACT_COVER_LOW,				ACT_COVER_PISTOL_LOW,			false },
	{ ACT_RANGE_AIM_LOW,			ACT_RANGE_AIM_PISTOL_LOW,		false },
	{ ACT_GESTURE_RELOAD,			ACT_GESTURE_RELOAD_PISTOL,		false },
};


IMPLEMENT_ACTTABLE( CWeaponDualies );

//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeaponDualies::CWeaponDualies( void )
{
	m_flSoonestPrimaryAttack = gpGlobals->curtime;
	m_flAccuracyPenalty = 0.0f;

	m_fMinRange1		= 24;
	m_fMaxRange1		= 1500;
	m_fMinRange2		= 24;
	m_fMaxRange2		= 200;

	m_bFiresUnderwater	= true;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponDualies::Precache( void )
{
	BaseClass::Precache();
}

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

			CAI_BaseNPC *npc = pOperator->MyNPCPointer();
			ASSERT( npc != NULL );

			vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin );

			CSoundEnt::InsertSound( SOUND_COMBAT|SOUND_CONTEXT_GUNFIRE, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_PISTOL, 0.2, pOperator, SOUNDENT_CHANNEL_WEAPON, pOperator->GetEnemy() );

			WeaponSound( SINGLE_NPC );
			pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2 );
			pOperator->DoMuzzleFlash();
			m_iClip1 = m_iClip1 - 1;
		}
		break;
		default:
			BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
			break;
	}
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponDualies::DryFire( void )
{
	WeaponSound( EMPTY );
	SendWeaponAnim( ACT_VM_DRYFIRE );
	
	m_flSoonestPrimaryAttack	= gpGlobals->curtime + DUALIES_FASTEST_DRY_REFIRE_TIME;
	m_flNextPrimaryAttack		= gpGlobals->curtime + SequenceDuration();
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponDualies::PrimaryAttack( void )
{
	if ( ( gpGlobals->curtime - m_flLastAttackTime ) > 0.5f )
	{
		m_nNumShotsFired = 0;
	}
	else
	{
		m_nNumShotsFired++;
	}

	m_flLastAttackTime = gpGlobals->curtime;
	m_flSoonestPrimaryAttack = gpGlobals->curtime + DUALIES_FASTEST_REFIRE_TIME;
	CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), SOUNDENT_VOLUME_PISTOL, 0.2, GetOwner() );

	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

	//Flipping Code -Jman
	if ( Flip == true )
	{
		BaseClass::PrimaryAttack();
		Flip = false;
		PostFireStuff();
	}
	else
	{
		BaseClass::RightDualiesAttack();
		Flip = true;
		PostFireStuff();
	}

	if( pOwner )
	{
		// Each time the player fires the dualies, reset the view punch. This prevents
		// the aim from 'drifting off' when the player fires very quickly. This may
		// not be the ideal way to achieve this, but it's cheap and it works, which is
		// great for a feature we're evaluating. (sjb)
		pOwner->ViewPunchReset();
	}

	BaseClass::PrimaryAttack();

	// Add an accuracy penalty which can move past our maximum penalty time if we're really spastic
	m_flAccuracyPenalty += DUALIES_ACCURACY_SHOT_PENALTY_TIME;
}

//Post Fire things.
void CWeaponDualies::PostFireStuff( void )
{
	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
	if( pOwner )
	{
		pOwner->ViewPunchReset();
	}

	// Add an accuracy penalty which can move past our maximum penalty time if we're really spastic
	m_flAccuracyPenalty += DUALIES_ACCURACY_SHOT_PENALTY_TIME;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponDualies::UpdatePenaltyTime( void )
{
	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

	if ( pOwner == NULL )
		return;

	// Check our penalty time decay
	if ( ( ( pOwner->m_nButtons & IN_ATTACK ) == false ) && ( m_flSoonestPrimaryAttack < gpGlobals->curtime ) )
	{
		m_flAccuracyPenalty -= gpGlobals->frametime;
		m_flAccuracyPenalty = clamp( m_flAccuracyPenalty, 0.0f, DUALIES_ACCURACY_MAXIMUM_PENALTY_TIME );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponDualies::ItemPreFrame( void )
{
	UpdatePenaltyTime();

	BaseClass::ItemPreFrame();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponDualies::ItemBusyFrame( void )
{
	UpdatePenaltyTime();

	BaseClass::ItemBusyFrame();
}

//-----------------------------------------------------------------------------
// Purpose: Allows firing as fast as button is pressed
//-----------------------------------------------------------------------------
void CWeaponDualies::ItemPostFrame( void )
{
	BaseClass::ItemPostFrame();

	if ( m_bInReload )
		return;
	
	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

	if ( pOwner == NULL )
		return;

	//Allow a refire as fast as the player can click
	if ( ( ( pOwner->m_nButtons & IN_ATTACK ) == false ) && ( m_flSoonestPrimaryAttack < gpGlobals->curtime ) )
	{
		m_flNextPrimaryAttack = gpGlobals->curtime - 0.1f;
	}
	else if ( ( pOwner->m_nButtons & IN_ATTACK ) && ( m_flNextPrimaryAttack < gpGlobals->curtime ) && ( m_iClip1 <= 0 ) )
	{
		DryFire();
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : int
//-----------------------------------------------------------------------------
Activity CWeaponDualies::GetPrimaryAttackActivity( void )
{
	if ( m_nNumShotsFired < 1 )
		return ACT_VM_PRIMARYATTACK;

	if ( m_nNumShotsFired < 2 )
		return ACT_VM_RECOIL1;

	if ( m_nNumShotsFired < 3 )
		return ACT_VM_RECOIL2;

	return ACT_VM_RECOIL3;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CWeaponDualies::Reload( void )
{
	bool fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
	if ( fRet )
	{
		WeaponSound( RELOAD );
		m_flAccuracyPenalty = 0.0f;
	}
	return fRet;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponDualies::AddViewKick( void )
{
	CBasePlayer *pPlayer  = ToBasePlayer( GetOwner() );
	
	if ( pPlayer == NULL )
		return;

	QAngle	viewPunch;

	viewPunch.x = random->RandomFloat( 0.25f, 0.5f );
	viewPunch.y = random->RandomFloat( -.6f, .6f );
	viewPunch.z = 0.0f;

	//Add it to the view punch
	pPlayer->ViewPunch( viewPunch );
}

c_weapon_stubs_hl2.cpp
Code:
STUB_WEAPON_CLASS( weapon_dualies, WeaponDualies, C_BaseHLCombatWeapon );

basecombatweapon_shared.cpp
Code:
//-----------------------------------------------------------------------------
// Purpose: Dualies Firing
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::RightDualiesAttack( void )
{
	// If my clip is empty (and I use clips) start reload
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{
		Reload();
		return;
	}

	// Only the player fires this way so we can cast
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	if (!pPlayer)
	{
		return;
	}

	// MUST call sound before removing a round from the clip of a CMachineGun
	WeaponSound(SINGLE);

	pPlayer->DoMuzzleFlash();

	SendWeaponAnim( GetSecondaryAttackActivity() );

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

	FireBulletsInfo_t info;
	info.m_vecSrc	 = pPlayer->Weapon_ShootPosition( );
	
	info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT );

	// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, 
	// especially if the weapon we're firing has a really fast rate of fire.
	info.m_iShots = 0;
	float fireRate = GetFireRate();

	while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
	{
		m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
		info.m_iShots++;
		if ( !fireRate )
			break;
	}

	// Make sure we don't fire more than the amount in the clip
	if ( UsesClipsForAmmo1() )
	{
		info.m_iShots = min( info.m_iShots, m_iClip1 );
		m_iClip1 -= info.m_iShots;
	}
	else
	{
		info.m_iShots = min( info.m_iShots, pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) );
		pPlayer->RemoveAmmo( info.m_iShots, m_iPrimaryAmmoType );
	}

	info.m_flDistance = MAX_TRACE_LENGTH;
	info.m_iAmmoType = m_iPrimaryAmmoType;
	info.m_iTracerFreq = 2;

#if !defined( CLIENT_DLL )
	// Fire the bullets
	info.m_vecSpread = pPlayer->GetAttackSpread( this );
#else
	//!!!HACKHACK - what does the client want this function for? 
	info.m_vecSpread = GetActiveWeapon()->GetBulletSpread();
#endif // CLIENT_DLL

	pPlayer->FireBullets( info );

	if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
	{
		// HEV suit - indicate out of ammo condition
		pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); 
	}

	//Add our view kick in
	AddViewKick();
}

basecombatweapon_shared.h
Code:
	virtual void			RightDualiesAttack( void );						// do right gun shot"

weapon_dualies.txt
Code:
// dualies
WeaponData
{
	// Weapon data is loaded by both the Game and Client DLLs.
	"printname"	"Executioners"
	"viewmodel"			"models/weapons/v_357.mdl"
	"playermodel"		"models/weapons/w_357.mdl"
	"anim_prefix"		"python"
	"bucket"			"1"
	"bucket_position"	"2"

	"clip_size"			"6"
	"default_clip"		"6"
	"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"	"l"
		}
		"weapon_s"
		{	
				"font"		"WeaponIconsSelected"
				"character"	"l"
		}
		"ammo"
		{
				"font"		"WeaponIcons"
				"character"	"z"
		}
		"crosshair"
		{
				"font"		"Crosshairs"
				"character"	"Q"
		}
		"autoaim"
		{
				"file"		"sprites/crosshairs"
				"x"			"0"
				"y"			"48"
				"width"		"24"
				"height"	"24"
		}
	}
}

Sorry I don't have a legit version of winzip lol, I believe that is all of it. I have no clue, I have done two tutorials and niether worked for me lol
 
im sure this isnt your problem but i just wanted to know if you've added the FGD entry ? .
 
i did that as well and it still says missing entity when loading the map, i am just so lost!
 
alright im just going to keep asking small stupid questions :P , cant really do much else because i dont have the sdk on me atm .
did you enter the "STUB_WEAPON_CLASS" bit in the right area ? it should be in the hl2sp weapons .
edit:put it above the "#ifndef HL2MP"
btw do you have msn ?
 
yeah that didnt work, i used to have msn, i havent used in so long, i will PM you my old hotmail address that i used with it and if u want to go on and chat about this ill sign on
 
Back
Top