So lets say you want to determine if a player is behind another player or monster. How would you do this? Well we have to take two equal vector lengths and find the relationship between them. We can do this with something called a Dot Product.
A Dot Product is an algebraic operation that takes two equal-length sequences of numbers and returns a single number. So what does this formula look like?
In Geometry/Trigonometry it looks like this:
A.B = |A| * |B| * cos(theta) : theta is the angle between the two points. //Fixed to lower confusion thanks Hypersonic
This is fine, but more computationally expensive for computer programming languages. We need a more algebraic expression of this. Luckily we have one.
A.B = A.x * B.x + A.y * B.y + A.z * B.z
So there you have it! How to calculate the dot product in a programming language using linear algebra!
Dot Products are used extensively in the Quake Engine Source Code. It is just that you never really see it. But without it quake wouldn't be possible.
But how do we use this to figure out if we are behind a monster?
Well before I mentioned that it returns a single integer. Depending on the number it returns, we can determine where we are in relation to the other vector. For instance, lets say we have the attacker with a view vector (direction he/she is pointing) as V1. And lets say the victim has a view vector of V2. We use the Dot Product to figure out the relationship. If it returns a value of 1 it means we are directly in front of the victim. This is not going to give us a backstab. Likewise if we get a return of 0. This is perpendicular to the victim (To his side). This is also not good enough to be a back stab. However, if we get a result of -1, this is indeed behind the victim and thus we can get a backstab result! The math is self explanatory. But here this is a picture to help visualize it.
So now that we have a better understanding of Dot Product lets make a function for one we can use in qc.
Ok, you can place that in weapons.qc near the top if you'd like. Now to put it to good use. Scroll down to the W_FireAxe routine. We will be placing this yellow highlighted code into the function:
And there you have it! Compile and if you can sneak up on an enemy from behind you will get a instant kill shot with the axe. Of course this probably shouldn't happen for Shamblers so you might want to tweak it. Now you understand Dot Product and a cool way to utilize it in qc. Have fun.
A Dot Product is an algebraic operation that takes two equal-length sequences of numbers and returns a single number. So what does this formula look like?
In Geometry/Trigonometry it looks like this:
A.B = |A| * |B| * cos(theta) : theta is the angle between the two points. //Fixed to lower confusion thanks Hypersonic
This is fine, but more computationally expensive for computer programming languages. We need a more algebraic expression of this. Luckily we have one.
A.B = A.x * B.x + A.y * B.y + A.z * B.z
So there you have it! How to calculate the dot product in a programming language using linear algebra!
Dot Products are used extensively in the Quake Engine Source Code. It is just that you never really see it. But without it quake wouldn't be possible.
But how do we use this to figure out if we are behind a monster?
Well before I mentioned that it returns a single integer. Depending on the number it returns, we can determine where we are in relation to the other vector. For instance, lets say we have the attacker with a view vector (direction he/she is pointing) as V1. And lets say the victim has a view vector of V2. We use the Dot Product to figure out the relationship. If it returns a value of 1 it means we are directly in front of the victim. This is not going to give us a backstab. Likewise if we get a return of 0. This is perpendicular to the victim (To his side). This is also not good enough to be a back stab. However, if we get a result of -1, this is indeed behind the victim and thus we can get a backstab result! The math is self explanatory. But here this is a picture to help visualize it.
So now that we have a better understanding of Dot Product lets make a function for one we can use in qc.
Code:
float (vector from, vector to) Dot = { return from_x * to_x + from_y * to_y + from_z * to_z; };
Code:
if (trace_ent.takedamage) { trace_ent.axhitme = 1; SpawnBlood (org, '0 0 0', 20); [COLOR="Lime"]// First we need to set view vectors for our trace_ent[/COLOR] [COLOR="Lime"]//If the trace_ent is a monster we will use angles instead of v_angles as monster entities do not utilize v_angles only clients[/COLOR] [COLOR="Yellow"]if (trace_ent.flags & FL_MONSTER) makevectors(trace_ent.angles); else makevectors(trace_ent.v_angle);[/COLOR] [COLOR="lime"]// Now lets set the view vector. [/COLOR] [COLOR="yellow"]def = -v_forward;[/COLOR] [COLOR="Lime"]// Now lets make new view vectors for the attacker(self)[/COLOR] [COLOR="Yellow"]makevectors(self.v_angle);[/COLOR] [COLOR="Lime"] // Now lets calculate the Dot Product and if it is less than -.05 we will do a kill shot to the victim. Note here that I used -0.5 and not -1. The reason for using < -0.5 is because this gives you some wiggle room in where you can hit the target from behind. Otherwise you'd always have to be directly behind the target to get the kill. [/COLOR] [COLOR="yellow"]if (Dot(v_forward, def) < -0.5) T_Damage (trace_ent, self, self, [COLOR="lime"]trace_ent.health[/COLOR]);[/COLOR] else T_Damage (trace_ent, self, self, 20); }
Comment