Cleanup is going to take awhile, so the site is back up but editing has been disabled.

Ironsights: Single Player

From HalfLife 2 Knowledge Base

Jump to: navigation, search

by Bourkey

Massive thanks to Cin

Please note: If using this code, weapons will have to be modeled so all sides are visible.

For the Multiplayer version of this code please go here: http://www.hl2world.com/wiki/index.php/Ironsights:_Multiplayer

Contents


Results

Tested and works!

Intro

HL2SP SDK

Great thanks to this man: Cin. http://www.bearkey.com/users/cin

If you have done this tutorial before with no luck you better remove the old code, because what is in here now is pretty much all new code.

The Goal

Is to create an ironsight system that do not include animation. It moves the origin of the weapon position up the Players eyes origin.

That was the original goal, now we have a little animation slide aswell.

The Project

The project is now done, it should work normally.

What is still left.

  • Remove crosshair on toggle - FIXED
  • Change the fov on toggle


weapon_parse.h

Add this in the bottom of the file. Only add the lines with //ADDED behind.

class FileWeaponInfo_t
{
public:

	FileWeaponInfo_t();
	//ironsight
	Vector m_expOffset; //ADDED
	QAngle m_expOriOffset; //ADDED
....
};

weapon_parse.cpp

Add this in the file.

void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponName )
{
...
   // this just saves off the data in the script file for later use
   KeyValues *pEt = pKeyValuesData->FindKey("ExpOffset");
   if (pEt)
   {
		m_expOffset.x     = pEt->GetFloat("x", 0.0f);
		m_expOffset.y     = pEt->GetFloat("y", 0.0f);
		m_expOffset.z     = pEt->GetFloat("z", 0.0f);

		m_expOriOffset.x  = pEt->GetFloat("xori", 0.0f);
		m_expOriOffset.y  = pEt->GetFloat("yori", 0.0f);
		m_expOriOffset.z  = pEt->GetFloat("zori", 0.0f);
   }
   else
   {
      m_expOffset = vec3_origin;
      m_expOriOffset.Init();
   }
...
}

baseviewmodel_shared.cpp

Change in the beginning of the file so it looks like this

#include "cbase.h"
#include "baseviewmodel_shared.h"

#if defined( CLIENT_DLL )
#include "iprediction.h"
#include "prediction.h"
// cin: 070105 - ironsight mode changes
#include "convar.h"
#include "c_baseplayer.h"
#include "c_basecombatweapon.h"

#else
#include "vguiscreen.h"
#endif

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

Then under that add so it should look like this.

#define VIEWMODEL_ANIMATION_PARITY_BITS 3
#define SCREEN_OVERLAY_MATERIAL "vgui/screens/vgui_overlay"
#if defined( CLIENT_DLL )
void ExpWpnTestOffset(ConVar *pConVar, char *pszString);
ConVar   cl_exp_test_wpn_offset("cl_exp_test_wpn_offset", "0", 0, "Tests weapon offsets",
      (FnChangeCallback)ExpWpnTestOffset);

ConVar   cl_exp_test_wpn_offset_x("cl_exp_test_wpn_offset_x", "0");
ConVar   cl_exp_test_wpn_offset_y("cl_exp_test_wpn_offset_y", "0");
ConVar   cl_exp_test_wpn_offset_z("cl_exp_test_wpn_offset_z", "0");

ConVar   cl_exp_test_wpn_ori_offset_x("cl_exp_test_wpn_ori_offset_x", "0");
ConVar   cl_exp_test_wpn_ori_offset_y("cl_exp_test_wpn_ori_offset_y", "0");
ConVar   cl_exp_test_wpn_ori_offset_z("cl_exp_test_wpn_ori_offset_z", "0");

// cin: 070105 - applies existing weapon offsets when
// entering test mode (this will not be called upon
// weapon change, so beware)
// this mode should only be used for calibrating the
// ironsighted mode offests for a particular weapon
void ExpWpnTestOffset(ConVar *pConVar, char *pszString)
{
   CBasePlayer *pPlayer = UTIL_PlayerByIndex(engine->GetLocalPlayer());
   if (pPlayer)
   {
      CBaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon();

      if (pWeapon)
      {
         cl_exp_test_wpn_offset_x.SetValue(pWeapon->GetWpnData().m_expOffset.x);
         cl_exp_test_wpn_offset_y.SetValue(pWeapon->GetWpnData().m_expOffset.y);
         cl_exp_test_wpn_offset_z.SetValue(pWeapon->GetWpnData().m_expOffset.z);

         cl_exp_test_wpn_ori_offset_x.SetValue(pWeapon->GetWpnData().m_expOriOffset.x);
         cl_exp_test_wpn_ori_offset_y.SetValue(pWeapon->GetWpnData().m_expOriOffset.y);
         cl_exp_test_wpn_ori_offset_z.SetValue(pWeapon->GetWpnData().m_expOriOffset.z);
      }
   }
}


// last time ironsighted mode was toggled
float gIronsightedTime(0.0f);

// i bound this to a key for testing(i.e. bind [ ironsight_toggle)
CON_COMMAND(ironsight_toggle, "toggles ironsight mode for the current weapon")
{
   if (gpGlobals->curtime - gIronsightedTime < 0.5f)
      return;

   CBasePlayer *pPlayer = UTIL_PlayerByIndex(engine->GetLocalPlayer());
   if (pPlayer)
   {
     C_BaseViewModel  *pVm = pPlayer->GetViewModel();
      if (pVm)
      {
		//pPlayer->m_Local.m_iHideHUD |= HIDEHUD_CROSSHAIR;)
         pVm->m_bExpSighted  ^= true;
         gIronsightedTime     = gpGlobals->curtime;
      }
   }
}

void CalcExpWpnOffsets(CBasePlayer *owner, Vector &pos, QAngle &ang)
{
   Vector   forward, right, up, offset;

   // this is a simple test mode to help determine the proper values
   // to place in the weapon script
   if (cl_exp_test_wpn_offset.GetBool())
   {
      ang.x      += cl_exp_test_wpn_ori_offset_x.GetFloat();
      ang.y      += cl_exp_test_wpn_ori_offset_y.GetFloat();
      ang.z      += cl_exp_test_wpn_ori_offset_z.GetFloat();
      offset.Init(cl_exp_test_wpn_offset_x.GetFloat(),
                  cl_exp_test_wpn_offset_y.GetFloat(),
                  cl_exp_test_wpn_offset_z.GetFloat());
   }
   else
   {
       CBaseCombatWeapon *pWeapon = owner->GetActiveWeapon();
      if (pWeapon)
      {
         ang        += pWeapon->GetWpnData().m_expOriOffset;
         offset      = pWeapon->GetWpnData().m_expOffset;
      }
   }

   // get eye direction angles
   AngleVectors(ang, &forward, &right, &up);

   // apply the offsets
   pos        += forward   * offset.x;
   pos        += right     * offset.y;
   pos        += up        * offset.z;
}
#endif

Scroll down some and you will find the ViewModel::Spawn Edit it to look like this:

void CBaseViewModel::Spawn( void )
{
	Precache( );
	SetSize( Vector( -8, -4, -2), Vector(8, 4, 2) );
	SetSolid( SOLID_NONE );

	#ifdef CLIENT_DLL
   // cin: 070105 - ironsighted mode changes
   m_bExpSighted  = false;
   m_expFactor    = 0.0f;
#endif


}

Animating the gun

Now while we are still in the file we need some more. Look for void CBaseViewModel::CalcViewModelView. Replace the whole function with this.

void CBaseViewModel::CalcViewModelView( CBasePlayer *owner, const Vector& eyePosition, const QAngle& eyeAngles )
{
   // UNDONE: Calc this on the server?  Disabled for now as it seems unnecessary to have this info on the server
#if defined( CLIENT_DLL )
   QAngle vmangoriginal = eyeAngles;
   QAngle vmangles = eyeAngles;
   Vector vmorigin = eyePosition;

   CBaseCombatWeapon *pWeapon = m_hWeapon.Get();
   //Allow weapon lagging
   if ( pWeapon != NULL )
   {
#if defined( CLIENT_DLL )
      if ( !prediction->InPrediction() )
#endif
      {
         pWeapon->AddViewmodelBob( this, vmorigin, vmangles );
         CalcViewModelLag( vmorigin, vmangles, vmangoriginal );
      }
   }

#if defined( CLIENT_DLL )
   if ( !prediction->InPrediction() )
   {
      // Let the viewmodel shake at about 10% of the amplitude of the player's view
      vieweffects->ApplyShake( vmorigin, vmangles, 0.1 );   
   }
#endif
   // cin: 070105 - ironsighted mode changes
   // get the wpn offsets
   CalcExpWpnOffsets(owner, vmorigin, vmangles);

   // get delta time for 1 sec interpolation and interpolate to/from positional offset
   float delta(gpGlobals->curtime - gIronsightedTime);
   m_expFactor = (m_bExpSighted) ? 
         (delta > 1.0f) ? 1.0f : delta :
         (delta > 1.0f) ? 0.0f : 1.0f - delta;
   Vector difPos(vmorigin - eyePosition);
   vmorigin = eyePosition + (difPos * m_expFactor);

   SetLocalOrigin(vmorigin);
   SetLocalAngles(vmangles);
#endif
}

Looks easy huh? What does it do then? The delta variables says what is what. 1.0 is when the gun is fully ironsighted, and 0.0 says when it is not sighted at all. So this codes calculates the distanse between and slide the gun from 0 to 1.

baseviewmodel_shared.h

You need to add a couple of public defines here.

class CBaseViewModel : public CBaseAnimating
{
	DECLARE_CLASS( CBaseViewModel, CBaseAnimating );
public:

	bool m_bExpSighted; //ADDED
	float m_expFactor; //ADDED

	DECLARE_NETWORKCLASS();
	DECLARE_PREDICTABLE();

#if !defined( CLIENT_DLL )
	DECLARE_DATADESC();
#endif

Extra

Some of you might think the gun is is moving up to the designated point a bit too slow, then here is the solution to it. Nothing hard nothing particular cool stuff, just 2 lines of code.

Look for this line: float gIronsightedTime(0.0f); Below it add this.

float gMoveTime(0.1f); //Seconds to use to move the model up to players view

Last line. Go to the delta float delta(gpGlobals->curtime - gIronsightedTime); Change it to look like this:

float delta((gpGlobals->curtime - gIronsightedTime) / gMoveTime);

Done! All we need to do is to change the script files. (MORE ADDED SOON)

weapon_pistol.txt

Add this somewhere in the script file.

   ExpOffset
   {
      "x"   "-15"
      "y"   "-5.5"
      "z"   "4.2"
     // "xori"   "-2.9" //Does not work
     // "yori"   "1.1" //Does not work
     // "zori"   "2.0" // Does not work
   }

CREDITS

Wraiyth, Cin (for the original idea), Bourkey for incorporating sp code.

Personal tools