View Full Version : Only when you duck and stand still?

Mero Vilul
06-03-2002, 01:48 PM
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 :)

Hell Raiser
06-03-2002, 01:55 PM
Well, I haven't had a chance to go through the JO source, but my guess would be to look for the rolling code (with lightsaber) and look for wherever it checks for the players speed and whether crouching is being pressed. :)

Mero Vilul
06-03-2002, 01:55 PM
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.

06-03-2002, 01:58 PM
For the speed part of the weapon, try looking at the Bryar Pistol's alternative fire code. That charges up as you hold the key.

Mero Vilul
06-03-2002, 03:16 PM
Yes of course... You guys made me see how simple it could be if I just put some thought in it... Thank you :)

At least I have figured out what to look at for a projetile that goes down :)

06-04-2002, 06:21 AM
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;

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) {
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.

Mero Vilul
06-04-2002, 05:40 PM
Wow, thanks a lot!

Never though anyone would give me this much information, with code and all... going to try it out now. I'll let you know how it turns out... (Well, I always mess things up :)