Forum

RL Kickback

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Postby Orion » Mon Oct 01, 2007 9:17 pm

The only problem is the direction in which the player (attacker)moves varies. Is there a way to make the player move backwards?


Yes. Change the line to this:

Code: Select all
makevectors (attacker.angles);
attacker.velocity = attacker.velocity - v_forward * 200;
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby redrum » Mon Oct 01, 2007 11:17 pm

Nice! You da man!
I want to learn so, what do those lines mean in laymans terms?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Orion » Mon Oct 01, 2007 11:46 pm

Well, makevectors() will create v_forward, v_up and v_right vectors.
As v_forward/up/right are global vectors, if you call a function that uses a v_forward without a makevectors() for example, v_forward will be the direction you (or other client) are facing. That's why W_FireLightning don't need to call makevectors() because it is called every frame in PlayerPreThink(), and called once in W_Attack().

And that's why attacker.velocity is using v_forward, just to make the attacker go backwards. And the attacker is goind backwards because the line is this:

Code: Select all
attacker.velocity = attacker.velocity - v_forward * 200;


If you change the minus (-) to plus (+), the attacker will go forward, and notice that there's no v_back, v_left, nor v_down. Just use negative values like the attacker velocity.
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby redrum » Wed Oct 03, 2007 3:30 am

Thanks for the lesson.

Rocket Jump is all messed up now :cry:
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Sajt » Wed Oct 03, 2007 4:13 am

Use .v_angle in the call to makevectors, not .angles.

angles is the one used for drawing player.mdl, and usually only includes a third of the player's pitch angle.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby Orion » Wed Oct 03, 2007 4:40 am

Sajt: no need to change makevectors() 'cuz we don't want to make an attacker when firing a rocket downward and hitting an enemy make the attacker fly upwards, so let makevectors() use self.angles, then the attacker will go more backwards than upwards.

redrum: Replace the makevectors() and attacker.velocity stuff by this:

Code: Select all
if (targ != attacker)
{
   makevectors (attacker.angles);
   attacker.velocity = attacker.velocity - v_forward * 200;
}


This will make you rocket jump normally, as T_RadiusDamage() calls T_Damage() on various entities at the same time, it'll be calling T_Damage() to yourself(attacker), but with half damage that when hitting an enemy. So it will check if the target(targ) is not yourself, if the target is yourself, then it will ignore that 2 lines.
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby redrum » Wed Oct 03, 2007 6:19 pm

Problem is that I have the code in weapons.qc now (W_FireRocket () ).
So it gets called when the weapon fires.
I had it in client.qc before and the code was being called when I pressed the button (didn't have the effect I was looking for especially with the sniper rifle which has a long delay).
In weapons.qc it doesn't recognize "attacker" or "targ".

So, either I get weapons.qc to understand "attacker" and "targ" or I need a way to call the actual weapon firing in client.qc.
Is there a way to do that?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Orion » Wed Oct 03, 2007 11:04 pm

It's obvious that in weapons.qc it doesn't recognize "attacker" or "targ", nor in client.qc.

"attacker" and "targ" are not global entities, they're only used in Killed(), ClientObituary(), T_RadiusDamage() and T_Damage().

But what do you want to do exactly?


Take a look at T_MissileTouch(), that is called when a rocket hits something. You'll see a T_Damage() and a T_RadiusDamage() call.

It looks like this:

Code: Select all
T_Damage (other, self, self.owner, damg );


"other" will be "targ", "self" will be "inflictor", and "self.owner" will be "attacker". They're recognized in T_Damage() only.

Notice that T_Damage() in T_MissileTouch() is only called in an entity that has health, if the entity is a player, it will call if he's not dead and when the rocket hits the player, not the ground or some other wall/ceiling near him.

See T_RadiusDamage():

Code: Select all
T_RadiusDamage (self, self.owner, 120, other);


"self" will be "inflictor", "self.owner" will be "attacker", and "other" will be "ignore" (only used in T_RadiusDamage(), this entity will be ignored to call T_Damage()).

That is, T_RadiusDamage() will ignore the "other", because if the rocket hits a player directly, it will be calling T_Damage(), if you change "other" to "world" in T_RadiusDamage, it will be calling T_Damage() twice at the same entity.

Hope this helps. :)
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby Chris » Wed Oct 03, 2007 11:22 pm

excuse it if the code is not perfect I'm typing this from memory at work..

add:

makevectors (self.v_angle);

self.velocity = self.velocity + v_forward * -200;

self being in reference to the player. Put this in one of your weapon's fire functions.
Chris
 
Posts: 79
Joined: Sat Aug 05, 2006 5:31 am

Postby Orion » Thu Oct 04, 2007 12:22 am

Yeah, but we don't want the player to go backwards when firing a weapon, we want the player to go backwards when another player takes damage, that's why these lines are in T_Damage().
But, redrum, if you change mind, you can use the code that Chris posted.
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby redrum » Thu Oct 04, 2007 2:43 am

Orion, I do want the player to move backward when the shot is fired.
Is there a way, in client.qc, to say:
if (player does not shoot a rocket at himself)?

Chris, thanks but I already have the code in weapons.qc.
The effect works fine with the exception of rocket jumping.
The kickback adversely affects the rocket jump.

So I want to create code that says:

Code: Select all
If (I do not fire a rocket at myself)
        makevectors (self.v_angle);
        self.velocity = self.velocity - v_forward * 200;


So that when i do fire a rocket at myself (rocket jump) the kickback code will not be executed.
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Orion » Thu Oct 04, 2007 2:55 am

Now I see.


Add this at W_FireRocket(), between the velocity stuff:

Code: Select all
if (cankick)
{
// velocity codes here
}


Now add this before T_MissileTouch():

Code: Select all
float cankick;


Now add this at the very bottom of T_MissileTouch(), before remove(self):

Code: Select all
cankick = FALSE;
if (vlen(self.owner.origin - self.origin) > 160)
   cankick = TRUE;


This will create a global float called "cankick", and it will check the length between the rocket's origin and your origin.

Man, what a hard work you gave me! :shock:
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby redrum » Thu Oct 04, 2007 3:47 am

Sorry :lol:
Keepin' you on your toes!
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Orion » Thu Oct 04, 2007 2:43 pm

Redrum, there's some mistakes in the code above... I think all the code is a mistake, because it is pretty imprecise, you have to delete the code I posted from T_MissileTouch().

But this code I'll give is the best solution, your problems are over! :D

Add this to W_FireRocket() before the if (cankick), and replace if (cankick) with the code below:

Code: Select all
traceline (self.origin, self.origin + v_forward*160, FALSE, self);
if (trace_fraction == 1)
{
// velocity stuff here
}


Let me explain.
traceline() will trace an invisible line between a point to another, in this case, the line will be traced between your current position plus 160 forward units in the direction you're facing.
160 units is the size of the area of effect of a grenade or rocket, you see 120 in T_RadiusDamage() calls, but in T_RadiusDamage() itself at combat.qc, you'll see that findradius() will search for damageable entities in a sphere of the size of the amount of damage plus 40 units.

trace_fraction in the fraction of the line, that is, if you're close to a wall, probably you'll be less than 160 units away, so the traceline() knows that the rocket you'll fire will hurt yourself, giving you a momentum velocity, and no kickback will be given.
If you're less than 160 units away from a wall, trace_fraction will be less than 1, it could be 0.6, 0.3, or so.

You can reduce the 160 in traceline() if you want the RL to don't kickback only when rocket jumping.

FALSE in traceline() means that the line won't go through players or monsters. TRUE means that the line will go through players or monsters.

And the last "self", is the entity that will be ignored by the line.
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby redrum » Thu Oct 04, 2007 7:36 pm

Beautiful explanation. That's how us noobs learn stuff!
Thanks.
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

PreviousNext

Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest