1 #include "g_local.h"
2 void MatrixJabAndHook(edict_t *ent);
3 void MatrixCharge(edict_t *ent);
4 void swoosh (edict_t *ent);
5
P_ProjectSource(gclient_t * client,vec3_t point,vec3_t distance,vec3_t forward,vec3_t right,vec3_t result)6 static void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result)
7 {
8 vec3_t _distance;
9
10 VectorCopy (distance, _distance);
11 if (client->pers.hand == LEFT_HANDED)
12 _distance[1] *= -1;
13 else if (client->pers.hand == CENTER_HANDED)
14 _distance[1] = 0;
15 G_ProjectSource (point, _distance, forward, right, result);
16 }
17
MatrixKungfu(edict_t * ent)18 void MatrixKungfu (edict_t *ent)
19 {
20
21 MatrixJabAndHook(ent);
22 MatrixCharge(ent);
23 }
MatrixJabAndHook(edict_t * ent)24 void MatrixJabAndHook(edict_t *ent)
25 {
26 vec3_t forward, right;
27 vec3_t offset, start;
28 trace_t tr;
29 vec3_t end;
30 int damage, kick, MOD, sum;
31 edict_t *target = NULL;
32 edict_t *blip = NULL;
33 vec3_t targetdir, blipdir, dir, AngleToTarget;
34 vec_t speed;
35 int dist;
36
37 if(ent->client->ps.stats[STAT_SPECTATOR])
38 return;
39 //if(ent->client->weaponstate == WEAPON_FIRING)
40 // return;
41 //might be cooler to be able to do kungfu and NOT wait for other shit.
42
43 if(ent->deadflag)
44 return;
45 if(ent->client->next_kungfu > level.framenum)
46 return;
47
48
49 while ((blip = findradius(blip, ent->s.origin, 100)) != NULL)
50 {
51 if (!(blip->svflags & SVF_MONSTER) && !blip->client)
52 continue;
53 if (blip == ent)
54 continue;
55 if (!blip->takedamage)
56 continue;
57 if (blip->health <= 0)
58 continue;
59 VectorSubtract(blip->s.origin, ent->s.origin, blipdir);
60 blipdir[2] += 16;
61 if ((target == NULL) || (VectorLength(blipdir) < VectorLength(targetdir)))
62 {
63 target = blip;
64 VectorCopy(blipdir, targetdir);
65 }
66 }
67 sum = fabs(ent->client->v_angle[YAW] - ent->oldvangles[YAW]);
68
69 if(sum > 180)
70 sum = 360 - sum;
71
72
73 // gi.cprintf (ent, PRINT_HIGH, "YAW = %i ",sum);
74 //
75 if (target != NULL)
76 {
77 VectorSubtract(target->s.origin, ent->s.origin, targetdir);
78 VectorNormalize(targetdir);
79 tr = gi.trace (ent->s.origin, NULL, NULL, target->s.origin, ent, MASK_MONSTERSOLID);
80 MOD = MOD_KICK;
81 damage = 60;
82 kick = 300;
83
84 if(sum> 100)//if you spin far enough, do damage
85 {
86 target->velocity[2] +=100;
87 T_Damage (target, ent, ent, targetdir, target->s.origin, target->s.origin, damage_spinkick->value, kick, 1, MOD_SWEEP);
88 ent->matrixflip = KUNGFU;
89 ent->KungFuAnim = SPINKICK;
90 if(level.framenum < ent->LastHit + 15)
91 {
92 ent->CumulativeDamage += damage_spinkick->value;
93 ent->HitStreak++;
94 ent->LastHit = level.framenum;
95 }
96 else
97 {
98 ent->HitStreak = 1;
99 ent->CumulativeDamage = damage_spinkick->value;
100 ent->LastHit = level.framenum;
101 }
102 ent->KungFuAnim = SPINKICK;
103 swoosh (ent);//swoosh noise
104
105 if (ent->solid != SOLID_NOT && sum> 100)
106 {
107 if(IsBlocking(target))
108 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/phitf2.wav"), 1, ATTN_NORM, 0);
109 else
110 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/kick1.wav"), 1, ATTN_NORM, 0);
111 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
112
113 ent->client->next_kungfu = level.framenum + reload_spinkick->value;
114
115 return;
116 }
117 }
118
119
120
121
122 }
123
124
125 // don't need to check for water
126
127 if (ent->OLDvertbuttons <= 0 &&
128 ent->vertbuttons>0 &&
129 !ent->groundentity &&
130 !ent->oldgroundentity) //hover kick must work even if no enemy in range.
131 {
132 MOD = MOD_KICK;
133 damage = 20;
134 kick = 1;
135 swoosh (ent);//swoosh noise
136
137 if(target != NULL && tr.fraction < 1.0 && tr.ent->takedamage && !tr.ent->deadflag && !ent->deadflag)
138 {
139 T_Damage (target, ent, ent, targetdir, target->s.origin, target->s.origin, damage_hoverkick->value, kick, 1, MOD_HOVER);
140 if(level.framenum < ent->LastHit + 15)
141 {
142 ent->CumulativeDamage += damage_hoverkick->value;
143 ent->HitStreak++;
144 ent->LastHit = level.framenum;
145 }
146 else
147 {
148 ent->HitStreak = 1;
149 ent->CumulativeDamage = damage_hoverkick->value;
150 ent->LastHit = level.framenum;
151 }
152 ent->KungFuAnim = HOVERKICK;
153
154 if (ent->solid != SOLID_NOT )
155 {
156 if(IsBlocking(target))
157 {
158 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/phitf2.wav"), 1, ATTN_NORM, 0);
159
160 }
161 else
162 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/phitf1.wav"), 1, ATTN_NORM, 0);
163 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
164 }
165
166 }
167 ent->client->next_kungfu = level.framenum + reload_hoverkick->value;
168
169
170 if (ent->velocity[2] > 0)
171 ent->velocity[2] += 100;
172 else
173 ent->velocity[2] += 120;
174 ent->matrixflip = KUNGFU;
175 ent->KungFuAnim = HOVERKICK;
176 }
177
178 AngleVectors (ent->client->v_angle, forward, right, NULL);
179 VectorScale (forward, 0, ent->client->kick_origin);
180 VectorSet(offset, 0, 0, ent->viewheight-4);
181 P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
182
183 VectorMA( start, 80, forward, end );
184
185 tr = gi.trace (ent->s.origin, NULL, NULL, end, ent, MASK_MONSTERSOLID);
186
187 if (tr.fraction < 1.0 && tr.ent->takedamage && !tr.ent->deadflag && !ent->deadflag)
188 {
189
190 if(ent->forwardbuttons<0)
191 return;
192
193 if (ent->OLDforwardbuttons == 0 && ent->forwardbuttons>0)
194 {
195 MOD = MOD_KICK;
196 damage = 20;
197 kick = 250;
198 T_Damage (tr.ent, ent, ent, forward, tr.endpos, tr.plane.normal, damage_hook->value, kick, 1, MOD_HOOK);
199 ent->matrixflip = KUNGFU;
200 ent->KungFuAnim = HOOK;
201 if(level.framenum < ent->LastHit + 15)
202 {
203 ent->CumulativeDamage += damage_hook->value;
204 ent->HitStreak++;
205 ent->LastHit = level.framenum;
206 }
207 else
208 {
209 ent->HitStreak = 1;
210 ent->CumulativeDamage = damage_hook->value;
211 ent->LastHit = level.framenum;
212 }
213 VectorClear(ent->velocity);
214 swoosh (ent);//swoosh noise
215 if (ent->solid != SOLID_NOT )
216 if(IsBlocking(tr.ent))
217 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/phitf2.wav"), 1, ATTN_NORM, 0);
218 else
219 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/kick1.wav"), 1, ATTN_NORM, 0);
220
221 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
222 ent->client->next_kungfu = level.framenum + reload_hook->value;
223 ent->client->kick_angles[0] = 16;
224 }
225 else
226 if (ent->OLDstrafebuttons <= 0 && ent->strafebuttons>0 && ent->forwardbuttons == 0)
227 {
228 MOD = MOD_KICK;
229 damage = 10;
230 kick = 50;
231 T_Damage (tr.ent, ent, ent, forward, tr.endpos, tr.plane.normal, damage_jab->value, kick, 1, MOD_JAB);
232 ent->matrixflip = KUNGFU;
233 ent->KungFuAnim = JAB;
234 if(level.framenum < ent->LastHit + 15)
235 {
236 ent->CumulativeDamage += damage_jab->value;
237 ent->HitStreak++;
238 ent->LastHit = level.framenum;
239 }
240 else
241 {
242 ent->HitStreak = 1;
243 ent->CumulativeDamage = damage_jab->value;
244 ent->LastHit = level.framenum;
245 }
246 VectorClear(ent->velocity);
247 swoosh (ent);//swoosh noise
248 if (ent->solid != SOLID_NOT )
249 if(IsBlocking(tr.ent))
250 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/phitf2.wav"), 1, ATTN_NORM, 0);
251 else
252 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/kick2.wav"), 1, ATTN_NORM, 0);
253
254 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
255 ent->client->next_kungfu = level.framenum + reload_jab->value;
256 ent->client->kick_angles[2] = -15;
257 }
258 else
259 if (ent->OLDstrafebuttons >= 0 && ent->strafebuttons<0 && ent->forwardbuttons == 0)
260 {
261 MOD = MOD_KICK;
262 damage = 10;
263 kick = 50;
264 T_Damage (tr.ent, ent, ent, forward, tr.endpos, tr.plane.normal, damage_jab->value, kick, 1, MOD_JAB);
265 ent->matrixflip = KUNGFU;
266 ent->KungFuAnim = JAB;
267 if(level.framenum < ent->LastHit + 15)
268 {
269 ent->CumulativeDamage += damage_jab->value;
270 ent->HitStreak++;
271 ent->LastHit = level.framenum;
272 }
273 else
274 {
275 ent->HitStreak = 1;
276 ent->CumulativeDamage = damage_jab->value;
277 ent->LastHit = level.framenum;
278 }
279 VectorClear(ent->velocity);
280 swoosh (ent);//swoosh noise
281
282 if (ent->solid != SOLID_NOT )
283 if(IsBlocking(tr.ent))
284 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/phitf2.wav"), 1, ATTN_NORM, 0);
285 else
286 gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/kick.wav"), 1, ATTN_NORM, 0);
287 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
288 ent->client->next_kungfu = level.framenum + reload_jab->value;
289 ent->client->kick_angles[2] = 15;
290 }
291 else
292 if (ent->OLDvertbuttons < 0 && ent->vertbuttons>=0 && ent->groundentity)
293 {
294 MOD = MOD_KICK;
295 damage = 80;
296 kick = 500;
297 tr.ent->velocity[2] += 200;
298 T_Damage (tr.ent, ent, ent, forward, tr.endpos, tr.plane.normal, damage_uppercut->value, kick, 1, MOD_UPPERCUT);
299 ent->matrixflip = KUNGFU;
300 ent->KungFuAnim = UPPERCUT;
301 if(level.framenum < ent->LastHit + 15)
302 {
303 ent->CumulativeDamage += damage_uppercut->value;
304 ent->HitStreak++;
305 ent->LastHit = level.framenum;
306 }
307 else
308 {
309 ent->HitStreak = 1;
310 ent->CumulativeDamage = damage_uppercut->value;
311 ent->LastHit = level.framenum;
312 }
313 VectorClear(ent->velocity);
314 swoosh (ent);//swoosh noise
315
316 if (ent->solid != SOLID_NOT )
317 if(IsBlocking(tr.ent))
318 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/phitf2.wav"), 1, ATTN_NORM, 0);
319 else
320 gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/phitf1.wav"), 1, ATTN_NORM, 0);
321
322 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
323 ent->client->next_kungfu = level.framenum + reload_uppercut->value;
324 ent->client->kick_angles[0] = -40;
325 }
326
327
328 }
329
330
331 VectorCopy(ent->client->v_angle, ent->oldvangles);//NB i am getting pissed off by this thing - WATCH IT.
332 }
333
MatrixCharge(edict_t * ent)334 void MatrixCharge(edict_t *ent) // if you go fast and run into an opponent, you push them back (no damage, just a shoulder charge)
335 //this was a good idea in theory, but it means that people are pushed back before you can hit them.
336 {
337
338 /*vec3_t forward, right;
339 vec3_t offset, start, speed;
340 trace_t tr;
341 vec3_t end;
342
343 AngleVectors (ent->client->v_angle, forward, right, NULL);
344 VectorScale (forward, 0, ent->client->kick_origin);
345 VectorSet(offset, 0, 0, ent->viewheight-4);
346 P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
347
348 VectorCopy (ent->velocity, forward);
349 VectorNormalize(forward);
350 VectorMA( start, 80, forward, end );
351
352 tr = gi.trace (ent->s.origin, NULL, NULL, end, ent, MASK_MONSTERSOLID);
353 //trace in direction of speed.
354
355 if(tr.fraction < 1.0 && tr.ent->takedamage && !tr.ent->deadflag && !ent->deadflag
356 && fabs(VectorLength(ent->velocity)) > 210
357 && fabs(VectorLength(tr.ent->velocity)) < 200)
358 {
359 VectorCopy(ent->velocity, speed);//temp speed
360 VectorCopy(tr.ent->velocity, ent->velocity);//player takes on enemy's speed
361 VectorMA(speed, 50, tr.ent->velocity, tr.ent->velocity);//player's original speed added onto enemie's
362
363 }
364 */
365
366 }
swoosh(edict_t * ent)367 void swoosh (edict_t *ent)
368 {
369 float sound;
370 sound = random() * 3;
371 if (sound <= 1)
372 {
373 gi.sound(ent, CHAN_WEAPON, gi.soundindex("misc/throw.wav"), 1, ATTN_NORM, 0);
374 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
375 }
376 else if (sound <= 2)
377 {
378 gi.sound(ent, CHAN_WEAPON, gi.soundindex("misc/throw.wav"), 1, ATTN_NORM, 0);
379 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
380 }
381 else if(sound <= 3)
382 {
383 gi.sound(ent, CHAN_WEAPON, gi.soundindex("misc/swish.wav"), 1, ATTN_NORM, 0);
384 PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
385 }
386 }
387
MatrixComboTally(edict_t * ent)388 void MatrixComboTally (edict_t *ent)
389 {
390 char string[1024];
391
392
393 if(ent->HitStreak > 1 && ent->LastHit == level.framenum - 15)
394 {
395
396
397 // send the layout
398 /*Com_sprintf (string, sizeof(string),
399 "xv 160 yv 180 string2 \"%i Hit Combo\" ", //combo
400 ent->HitStreak);
401
402 gi.WriteByte (svc_layout);
403 gi.WriteString (string);
404 gi.unicast (ent, true);*/
405 if(combomessage->value)
406 {
407 gi.cprintf (ent, PRINT_CHAT, "%i Hit Combo: %i Damage Done\n", ent->HitStreak, (ent->CumulativeDamage * (2 + ent->damagelevel))/2);
408 if(ent->CumulativeDamage >= 100)
409 gi.sound(ent, CHAN_VOICE, gi.soundindex("frags/combo.wav"), 1, ATTN_NORM, 0);
410 }
411 if(ent->LastHit == level.framenum - 15)
412 ent->HitStreak = 0;
413 ent->CumulativeDamage = 0;
414 }
415
416 if(ent->HitStreak && ent->LastHit < level.framenum - 15)
417 {
418 ent->HitStreak = 0;
419 ent->CumulativeDamage = 0;
420 }
421
422 }
423
IsBlocking(edict_t * ent)424 int IsBlocking (edict_t *ent)
425 {
426 if(!ent->client)
427 return false;
428
429 if(strcmp(ent->client->pers.weapon->classname, "weapon_fists") == 0 //if you're using fists or knoves you can block
430 || strcmp(ent->client->pers.weapon->classname, "weapon_knives") == 0)
431 if(ent->forwardbuttons <= 0 && ent->strafebuttons == 0 && ent->client->next_kungfu <= level.framenum && ent->client->weaponstate != WEAPON_FIRING)
432 return true;
433 return false;
434
435
436 }
437
438