Jump to content

Home

Only when you duck and stand still?


Mero Vilul

Recommended Posts

Ok, I'm pretty new to this I might add, but I want the weapon I'm changing to only be usable when you are ducking and standing still.

 

Or maybe that if you're moving, you will stop, and then shoot. If you're crouching too that is.

 

Well, please help if you want and have the time, or else go have fun :)

Link to comment
Share on other sites

I know I can set the projectile speed very easily, but I want the speed to be changed depending on how long you press the fire key... let's say the maximum time to fire is 2 seconds, then it will fire with full speed, but If you just tap and release, it will fire with the minimum speed, and anywhere inbetween with a "minspeed + (% of the 2 second max time the button is held"... for eg min = 10, max = 100... I hold it for 1 sec (50%), It will have the speed 50...

 

Much to ask for probably, and I guess I have to find it out for my own... or? any hints at all is welcome. values to use and such...

 

And yes, it will be a mortar kind of weapon.

Link to comment
Share on other sites

It took me a while but I think I've figured out how to do this. I say "think" since I haven't tested in a real multiplayer game, only against bots.

 

There are two problems we need to solve.

 

Firstly and most obviously we want the server to disallow a player from firing unless he is crouched and stationary. The second problem isn't immediately apparent. When you press the fire button, the client code handily draws the muzzle flash and plays the firing sound for you and then waits for the server to actually tell it where to draw the weapon's projectile. We need to stop this from happening.

 

The server-side code goes in bg_pmove.c. The function we want to modify is PM_Weapon().

 

Somewhere near the top of the function there's a block which checks whether the player is in an ATST. After that block we can add the following code (which will work for the Bryar pistol; you can modify it for your new weapon just by changing WP_BRYAR_PISTOL to whatever you choose):

 

  /* can't fire Bryar unless ducked and stationary */
 if (pm->ps->weapon == WP_BRYAR_PISTOL) {
   if (pm->cmd.forwardmove || pm->cmd.rightmove || pm->cmd.upmove >= 0) {
     /* cancel any previous charge we had (can't charge, move and then fire) */
     pm->cmd.buttons &= ~BUTTON_ALT_ATTACK;
     /* set weapon to ready state; no longer charging */
     pm->ps->weaponstate = WEAPON_READY;
     return;
   }
 }

 

The firing function will return without doing anything if we have the Bryar and we aren't crouched and still. The "cancel any previous charge" thing makes the game forget we pressed alt fire and the weapon was ever charging. This is because otherwise you could crouch long enough to start charging, move about and then stop and crouch, release fire and let off a powerful shot. The code forces you to be stopped and crouched the whole time you are charging up your shot.

 

Next thing is to modify the function that actually fires the weapon. Here it's WP_FireBryarPistol() but you'd have to make a new function for your new weapon:

 

static void WP_FireBryarPistol(gentity_t *ent, qboolean altFire) {
 int damage = BRYAR_PISTOL_DAMAGE;
 float mul;
 gentity_t *missile;

 if (altFire) {
   /* calculate a speed multiplier; 100% for a 2s charge, min 10% */
   mul = (level.time - ent->client->ps.weaponChargeTime) / 2000.0f;
   if (mul < 0.1) mul = 0.1;
   else if (mul > 1.0) mul = 1.0;
 }
 else {
   /* primary fire has the base 10% */
   mul = 0.1;
 }

 missile = CreateMissile(muzzle, forward, BRYAR_PISTOL_VEL * mul, 10000, ent, altFire);

 /* rest of function */

 

For this Bryar pistol example we also need to comment out the whole "if (altFire)" block which follows and then keep the rest of the function intact.

 

To solve the client-side problem we open up cg_weapons.c and find CG_FireWeapon(). This is the function which is called when the server says that a player has fired. Theoretically (this is the part I haven't been able to test) this function won't be called if a remote player tries to fire because the server code we fixed above won't get as far as sending a "player fired" event. However, the function is called locally on the assumption that the server will later confirm a shot.

 

The code to insert comes just after the initialisation of weapon ("weap = &cg_weapons[ ent->weapon ];"):

 

 if (ent->weapon == WP_BRYAR_PISTOL) {
   /* is it us? */
   if (cg.predictedPlayerState.clientNum == cent->currentState.number) {
     if (cg_pmove.cmd.forwardmove) return;
     if (cg_pmove.cmd.rightmove) return;
     if (cg_pmove.cmd.upmove >= 0) return;
   }
 }

 

Practically the same as the server code. We check the command which was issued (cg_pmove.cmd) and return from the function without drawing any graphics or playing any sounds if the player is not stationary or if he isn't crouched. forwardmove will be >0 if he's moving forward, <0 if he's moving backwards and so we check for 0. Similarly for rightmove. upmove will be <0 when crouched so we return if it's non-negative.

 

The main problem which is NOT solved is that charging the pistol uses energy, which is lost if it isn't actually fired. You could get round this easily enough if you wanted to by including another test for the Bryar later on in PM_Weapon(). Then again maybe you want the player to waste energy. Depends how your weapon will work.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...