Quick Grenade: Difference between revisions
(Created page with "This is a copy and paste tutorial for adding a quick grenade function seen in many newer games. What this will do is simply holster the viewmodel, create a second viewmodel wi...") |
No edit summary |
||
Line 174: | Line 174: | ||
Okay, you have all of that? It compiles? | Okay, you have all of that? It compiles? | ||
If not, leave me an angry message telling me why I should not exist and I'll get right onto fixing it. | If not, leave me an angry message telling me why I should not exist [[User:ExoBacon|here]] and I'll get right onto fixing it. | ||
If so, start the game, bind a key to +throwgrenade, give yourself some grenades and a weapon (just use "impulse 101" to give you everything) and see what happens. Hopefully the gun should holster, then throw a grenade then draw the weapon again. | If so, start the game, bind a key to +throwgrenade, give yourself some grenades and a weapon (just use "impulse 101" to give you everything) and see what happens. Hopefully the gun should holster, then throw a grenade then draw the weapon again. | ||
==Credits== | ==Credits== | ||
One tired programmer who hasn't had his coffee fix | *One tired programmer who hasn't had his coffee fix | ||
Valve | *Valve | ||
==Editing/Usage== | ==Editing/Usage== | ||
*Edit this code if there is a better way to implement this or if you see a fix to a problem that has arisen. | |||
*Use wherever you want |
Revision as of 18:32, 25 January 2015
This is a copy and paste tutorial for adding a quick grenade function seen in many newer games. What this will do is simply holster the viewmodel, create a second viewmodel with the v_grenade model, play the throw animation, remove the second viewmodel then draw the first viewmodel. Has been tested on a near-new Source 2013 codebase.
Requirements
- A brain (This one is REALLY important)
- Knowledge of how to copy and paste text
Creating the throw button
First file is in_buttons.h. Add this to the end:
#define IN_THROWGRENADE (1 << 26)
NOTE: You see how the last number on that line is 26? Well if you look at the in_buttons file you will see that the last number in each line counts upwards from 0. So for instance if the last line on the defines is 30, your new line should end with 31. Got that?
Second piece of code is in in_main.cpp. First thing your going to have to search for is a big clump of lines starting with CalcButtonBits. It should start at approximately line 1457.
CalcButtonBits(bits, IN_THROWGRENADE, s_ClearInputState, &in_throwgrenade, bResetState);
Now we have to jump up to the top of the file and define in_throwgrenade. Just below the includes and convars there should be a bunch of lines starting with kbutton_t. We just add this code to the bottom of the final kbutton_t.
kbutton_t in_throwgrenade;
Then we go down a bit further to where all the keys are worked out. Just search for void IN_Attack3Up and stick this directly below it.
void IN_ThrowGrenadeDown(const CCommand &args) { KeyDown(&in_throwgrenade, args[1]); }
void IN_ThrowGrenadeUp(const CCommand &args) { KeyUp(&in_throwgrenade, args[1]); }
Now we search for where all the code can be called by the player with ConCommands. The lines should start with "static ConCommand" at approximately line 1570. Put this after the last "static ConCommand"
static ConCommand startgrenadethrow("+throwgrenade", IN_ThrowGrenadeDown);
static ConCommand endgrenadethrow("-throwgrenade", IN_ThrowGrenadeUp);
The Actual Function
First file is hl2_player.h (or hl2mp_player.h or sdk_player.h) Go down to line 263 and you should see the code declaration
void HandleSpeedChanges( void );
If you don't, search for it.
Once you've found that line, paste these underneath it.
void HandleThrowGrenade(void);
void ThrowGrenade(void);
void CreateGrenade(void);
Then scroll down a bit right to the end of that class where you should see the line
friend class CHL2GameMovement;
Again, if you don't, search for it
And again, paste these underneath.
float timeholster;
float timethrow;
float timedeploy;
bool WantThrow;
Now we move to hl2_player.cpp.
You can put this anywhere in the file, I put it underneath HandleSpeedChanges.
void CHL2_Player::HandleThrowGrenade(void)
{
if ((m_afButtonPressed & IN_THROWGRENADE) && !WantThrow && HasAnyAmmoOfType(12) && HasWeapons())
{
timeholster = NULL;
timethrow = NULL;
timedeploy = NULL;
WantThrow = true;
}
ThrowGrenade();
}
void CHL2_Player::ThrowGrenade(void)
{
if (WantThrow)
{
CBaseViewModel *vm = GetViewModel(0);
CBaseViewModel *vm2 = GetViewModel(1);
//2nd viewmodel creation
if (!vm2)
{
CreateViewModel(1);
vm2 = GetViewModel(1);
}
//HOLSTER SEQUENCING
int sequence1 = vm->SelectWeightedSequence(ACT_VM_HOLSTER);
if ((timeholster == NULL) && (sequence1 >= 0))
{
vm->SendViewModelMatchingSequence(sequence1);
timeholster = (gpGlobals->curtime + vm->SequenceDuration(sequence1) + 0.5f);
}
//THROW SEQUENCING
if ((timeholster < gpGlobals->curtime) && (timeholster != NULL))
{
vm->AddEffects(EF_NODRAW);
vm2->SetWeaponModel("models/weapons/v_grenade.mdl", NULL);
int sequence2 = vm2->SelectWeightedSequence(ACT_VM_THROW);
if ((timethrow == NULL) && (sequence2 >= 0))
{
vm2->SendViewModelMatchingSequence(sequence2);
timethrow = (gpGlobals->curtime + vm2->SequenceDuration(sequence2));
CreateGrenade();
}
}
if ((timethrow < gpGlobals->curtime) && (timethrow != NULL))
{
vm2->SetWeaponModel(NULL, NULL);
UTIL_RemoveImmediate(vm2);
vm->RemoveEffects(EF_NODRAW);
int sequence3 = vm->SelectWeightedSequence(ACT_VM_DRAW);
if ((timedeploy == NULL) && (sequence3 >= 0))
{
vm->SendViewModelMatchingSequence(sequence3);
timedeploy = (gpGlobals->curtime + vm->SequenceDuration(sequence3));
}
}
if ((timedeploy < gpGlobals->curtime) && (timedeploy != NULL))
{
//Successfully Thrown A Grenade! Decrement ammo
RemoveAmmo(1, 12);
WantThrow = false;
}
}
}
void CHL2_Player::CreateGrenade(void)
{
Vector vecEye = EyePosition();
Vector vForward, vRight;
EyeVectors(&vForward, &vRight, NULL);
Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f;
trace_t tr;
UTIL_TraceHull(vecEye, vecSrc, -Vector(4.0f + 2, 4.0f + 2, 4.0f + 2), Vector(4.0f + 2, 4.0f + 2, 4.0f + 2),
PhysicsSolidMaskForEntity(), this, GetCollisionGroup(), &tr);
if (tr.DidHit())
{
vecSrc = tr.endpos;
}
vForward[2] += 0.1f;
Vector vecThrow;
GetVelocity(&vecThrow, NULL);
vecThrow += vForward * 1200;
Fraggrenade_Create(vecSrc, vec3_angle, vecThrow, AngularImpulse(600, random->RandomInt(-1200, 1200), 0), this, 3.0f, false);
gamestats->Event_WeaponFired(this, true, GetClassname());
}
Okay, you have all of that? It compiles? If not, leave me an angry message telling me why I should not exist here and I'll get right onto fixing it. If so, start the game, bind a key to +throwgrenade, give yourself some grenades and a weapon (just use "impulse 101" to give you everything) and see what happens. Hopefully the gun should holster, then throw a grenade then draw the weapon again.
Credits
- One tired programmer who hasn't had his coffee fix
- Valve
Editing/Usage
- Edit this code if there is a better way to implement this or if you see a fix to a problem that has arisen.
- Use wherever you want