|
|
|
Original Code is in Yellow.
New Code is in red.
Deleted original code is in striketroughed gray.
As I learned english as third language in school, excuse some mistakes... (but
the c++ which is my fifth computer language should be okay *g*)
First of all, we got to make the Clipsize a bit higher. To do this, open weapons.h and change:
line 114
//#define
ROCKET_MAX_CARRY 5
#define ROCKET_MAX_CARRY 20 //rocket launcher ammo capacity
is now 20
line 132
//#define
RPG_MAX_CLIP 1
but if you want it to be soldier-style (or shotgun-style), change it to:
#define RPG_MAX_CLIP 5 //now a rocket launcher clip can
hold up to 5 missles
line 150
//#define
RPG_DEFAULT_GIVE 1
#define RPG_DEFAULT_GIVE 5 //Rocket Launcher spawns with 5
missles
I think there isn't much to explain :)
Now, you'll need
to change everyting as it is described here:
First of all, we'll change in line 27:
enum rpg_e {
RPG_IDLE
= 0,
RPG_FIDGET,
RPG_RELOAD, // to reload
RPG_FIRE2, // to empty
RPG_HOLSTER1, // loaded
RPG_DRAW1, // loaded
RPG_HOLSTER2, // unloaded
RPG_DRAW_UL, // unloaded
RPG_REL_START, //reload start
sequence (1000 ms)
RPG_REL_CYCLE, //reload main sequence (1500 ms)
RPG_REL_END, //reload end sequence (1000 ms)
RPG_IDLE_UL, // unloaded idle
RPG_FIDGET_UL, // unloaded fidget
};
Now what does little thing of code
do?
It's all easy. enum is some kind of list. Instead of writing
RPG_IDLE = 0;
RPG_FIDGET = 1;
RPG_FIRE2 = 2;
and so on, the compiler just replaces RPG_DRAW_UL with 6.
If you take a look at the original v_rpg.mld file, you will find out that animation
0 is named IDLE, animation 1 is named fidget etc. It's just names for the animation
numbers.
Now why did we change that? It's all easy. We'll replace the old v_rpg.mdl file
with the tfc variation: v_tfc_rpg.mdl which has different animations for reloading.
We need a little change in rpg.cpp
line 84
int m_cActiveRockets;// how many missiles in flight from
this launcher right now?
int m_fInReload; //Are we in reload? (0 means no)
normally, m_fInReload is used in by the default functions to see if the weapon
is in reload, but as we redefine it here, it's in a new class and new namespace
or something so that the default functions (in weapons.h and .cpp) can't change
it. or something like it :)
line 89
TYPEDESCRIPTION CRpg::m_SaveData[] =
{
DEFINE_FIELD( CRpg, m_fSpotActive, FIELD_INTEGER ),
DEFINE_FIELD( CRpg, m_cActiveRockets, FIELD_INTEGER ),
DEFINE_FIELD( CRpg, m_fInReload, FIELD_INTEGER),
};
IMPLEMENT_SAVERESTORE( CRpg, CBasePlayerWeapon );
I don't really know what this does,
but it was the same in the shotgun.cpp which I stole most of the changes :)
It's propably something about saving information and sending it to client.dll
or other players.
Now, there are some changes in CRpg::Reload(
) but we will do this at the end of the tutorial because all the prior changes
will create the basics for the changes in CRpg:Reload( )
in function CRpg::Spawn ( )
m_fSpotActive = 1;
m_fInReload = 0; //doesn't start to reload when spawned :)
if ( g_pGameRules->IsMultiplayer() )
{
//
more default ammo in multiplay. m_iDefaultAmmo
= RPG_DEFAULT_GIVE;
m_iDefaultAmmo = RPG_DEFAULT_GIVE * 2;
}
else {}
//With our higher Ammo Size, you don't need to give more Ammo
in multi-player
I got a good explanation for this change in WeaponIdle, so please be patient.
Done this? Change that:
in Rpg::Deploy( )
if ( m_iClip
== 0 )
{
return DefaultDeploy( "models/v_tfc_rpg.mdl",
"models/p_rpg.mdl", RPG_DRAW_UL, "rpg" );
}
return DefaultDeploy( "models/v_tfc_rpg.mdl", "models/p_rpg.mdl",
RPG_DRAW1, "rpg" ); }
in function CRpg::Precache
//PRECACHE_MODEL("models/v_rpg.mdl");
PRECACHE_MODEL("models/v_tfc_rpg.mdl");
Uses the tfc animation for the player view. In order to
make this change really effective, extract the v_tcf_rpg.mdl file from /tfc/pak0.pak
and put in YourModFolderHere/models/v_rfc_rpg.mdl.
But I don't know if Valve is alright with you using tfc stuff in your mod so
ask them first. I don't want to have anything to do with possible or impossible
copyright violations...
in function CRpg::PrimaryAttack ( )
else
{
PlayEmptySound( );
Reload( ); //when you're trying to fire an empty rpg, it reloads
instead
}
in function CRpg::WeaponIdle( )
if (m_flTimeWeaponIdle > gpGlobals->time)
return;
if (m_fInReload || !m_iClip) { Reload( ); return; } //reloads
automatically if empty
Well in fact it SHOULD
reload automatically but sometimes it waits some seconds to do so. (because
of if (m_flTimeWeaponIdle > gpGlobals->time) {return}; )
now normally, when you collect a missle in singleplayer, you get one. But in
multiplayer, you get two. Now, with the higher Clip size 5 (AMMO_RPGCLIP_GIVE),
you wouldn't want to get 10 (2*AMMO_RPGCLIP_GIVE) missles. that's too much.
in function CRpg::CRpgAmmo
if ( g_pGameRules->IsMultiplayer() ) iGive = AMMO_RPGCLIP_GIVE;
{
// hand out more ammo per rocket in multiplayer.
iGive = AMMO_RPGCLIP_GIVE * 2;
}
else
{
//With this higher Ammo Size, you don't need to give more
Ammo in multi-player
}
It's about the same in the Spawn( )
function (near line 425), the only difference is the name: RPG_DEFAULT_GIVE
thats why you changed that above.
Now, you could think that everything is done. But if you reload now, you see
that you put one missle in the launcher and you reloaded a full clip. As this
is unrealistic, we'll do a shotgun style reload now (or a tfc soldier style).
In order to do that, we got to change the Reload ( ) function. delete the function
and replace it with that:
(I had to replace every tab with 4 blanks but i hope I didn't ruin your day)
void CRpg::Reload( void )
{
if (m_flNextPrimaryAttack > gpGlobals->time)
return;
// check to see if we're ready to reload
if (m_fInReload == 0)
{
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]
<= 0 || m_iClip == RPG_MAX_CLIP)
{
m_fInReload
= 0;
return;
// don't
bother with any of this if don't need to reload.
}
m_fInReload = 1;
SendWeaponAnim ( RPG_REL_START
);
m_flTimeWeaponIdle = gpGlobals->time
+ 1;
m_flNextPrimaryAttack = gpGlobals->time
+ 1;
return;
}
else if (m_fInReload == 1)
{
m_fInReload
= 3;
// Add
them to the clip
if (m_iClip < RPG_MAX_CLIP &&
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]>0)
{
//start
the Weapon model animation and wait
SendWeaponAnim(
RPG_REL_CYCLE );
m_flTimeWeaponIdle
= gpGlobals->time + 1.4;
m_flNextPrimaryAttack
= gpGlobals->time + 1.4;
m_fInReload
= 2;
}
}
else if (m_fInReload == 2)
{
m_iClip += 1;
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]
-= 1;
//wait until the launcher moved
back, then start over
m_flTimeWeaponIdle = gpGlobals->time
+ .1;
m_flNextPrimaryAttack = gpGlobals->time
+ .1;
//when finished with that, reload
another missle
m_fInReload = 1;
//if the launcher is full or
if there are no more (less that one) missles, let him go back, then set m_fInReload
= 0
if (m_iClip >= RPG_MAX_CLIP
|| m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] < 1) { m_fInReload = 3; }
}
else if (m_fInReload == 3)
{
SendWeaponAnim(RPG_REL_END);
m_flTimeWeaponIdle = gpGlobals->time
+ 1;
m_flNextPrimaryAttack = gpGlobals->time
+ 1;
m_fInReload = 0;
}
}
Uh, it looks to me that this could need a little bit of explanation.
First of all, the function checks if it's called too early and stops in that
case. (if (m_flNextPrimaryAttack > gpGlobals->time) return;)
Then, it checks if there already is enough ammo in the Clip or if there's no
ammo left. (if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == RPG_MAX_CLIP))
Then, it sets m_fInReload to 1 which indicates a succesful start of the reload
cycle and shows the starting animation.
When m_fInReload is 1, it checks if there still is something to reload and,
in that case, it starts the animation where the yellow hand puts a new missle
in the launcher.
At the moment when m_fInReload is 2, the hand just finished putting that missle
in the rpg, so that we can really add it (m_iClip += 1; m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]
-= 1;).
Now, if there still is ammo and stuff, it does it again (m_fInReload = 1) otherwise,
it ends the reload and sets it to 3.
If m_fInReload is finally 3, it sends the end animation (where the launcher
gets back to be ready to fire) and sucessfully ends the reloading phase signaling
m_fInReload = 0;
Any questions or suggestions should be sent to me:
daMaker@gmx.net