46 side = DotProduct(velocity,
right);
47 sign = side < 0 ? -1 : 1;
52 if (side < sv_rollspeed->value)
73 float realcount, count, kick;
76 static vec3_t power_color = {0.0, 1.0, 0.0};
77 static vec3_t acolor = {1.0, 1.0, 1.0};
78 static vec3_t bcolor = {1.0, 0.0, 0.0};
80 client = player->client;
83 client->ps.stats[STAT_FLASHES] = 0;
84 if (client->damage_blood)
85 client->ps.stats[STAT_FLASHES] |= 1;
87 client->ps.stats[STAT_FLASHES] |= 2;
90 count = (client->damage_blood + client->damage_armor + client->damage_parmor);
95 if (client->anim_priority <
ANIM_PAIN && player->s.modelindex == 255) {
99 if (client->ps.pmove.pm_flags & PMF_DUCKED) {
127 r = 1 + (rand() & 1);
128 player->pain_debounce_time =
level.
time + 0.7;
129 if (player->health < 25)
131 else if (player->health < 50)
133 else if (player->health < 75)
137 gi.sound(player, CHAN_VOICE,
gi.soundindex(
va(
"*pain%i_%i.wav", l, r)), 1, ATTN_NORM, 0);
141 if (client->damage_alpha < 0)
142 client->damage_alpha = 0;
143 client->damage_alpha += count * 0.01;
144 if (client->damage_alpha < 0.2)
145 client->damage_alpha = 0.2;
146 if (client->damage_alpha > 0.6)
147 client->damage_alpha = 0.6;
152 if (client->damage_parmor)
153 VectorMA(v, (
float)client->damage_parmor / realcount, power_color, v);
154 if (client->damage_armor)
155 VectorMA(v, (
float)client->damage_armor / realcount, acolor, v);
156 if (client->damage_blood)
157 VectorMA(v, (
float)client->damage_blood / realcount, bcolor, v);
158 VectorCopy(v, client->damage_blend);
164 kick = abs(client->damage_knockback);
165 if (kick && player->health > 0) {
166 kick = kick * 100 / player->health;
168 if (kick < count * 0.5)
173 VectorSubtract(client->damage_from, player->s.origin, v);
176 side = DotProduct(v,
right);
177 client->v_dmg_roll = kick * side * 0.3;
179 side = -DotProduct(v,
forward);
180 client->v_dmg_pitch = kick * side * 0.3;
188 client->damage_blood = 0;
189 client->damage_armor = 0;
190 client->damage_parmor = 0;
191 client->damage_knockback = 0;
225 angles = ent->client->ps.kick_angles;
231 ent->client->ps.viewangles[ROLL] = 40;
232 ent->client->ps.viewangles[PITCH] = -15;
233 ent->client->ps.viewangles[YAW] = ent->client->killer_yaw;
237 VectorCopy(ent->client->kick_angles, angles);
244 ent->client->v_dmg_pitch = 0;
245 ent->client->v_dmg_roll = 0;
247 angles[PITCH] += ratio * ent->client->v_dmg_pitch;
248 angles[ROLL] += ratio * ent->client->v_dmg_roll;
255 angles[PITCH] += ratio * ent->client->fall_value;
259 delta = DotProduct(ent->velocity,
forward);
260 angles[PITCH] += delta *
run_pitch->value;
262 delta = DotProduct(ent->velocity,
right);
263 angles[ROLL] += delta *
run_roll->value;
268 if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
270 angles[PITCH] += delta;
272 if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
276 angles[ROLL] += delta;
287 v[2] += ent->viewheight;
294 v[2] -= ratio * ent->client->fall_value * 0.4;
306 VectorAdd(v, ent->client->kick_origin, v);
324 VectorCopy(v, ent->client->ps.viewoffset);
341 ent->client->ps.gunangles[ROLL] = -ent->client->ps.gunangles[ROLL];
342 ent->client->ps.gunangles[YAW] = -ent->client->ps.gunangles[YAW];
348 for (i = 0 ; i < 3 ; i++) {
349 delta = ent->client->oldviewangles[i] - ent->client->ps.viewangles[i];
359 ent->client->ps.gunangles[ROLL] += 0.1 * delta;
360 ent->client->ps.gunangles[i] += 0.2 * delta;
364 VectorClear(ent->client->ps.gunoffset);
368 for (i = 0 ; i < 3 ; i++) {
369 ent->client->ps.gunoffset[i] +=
forward[i] * (
gun_y->value);
370 ent->client->ps.gunoffset[i] +=
right[i] *
gun_x->value;
371 ent->client->ps.gunoffset[i] +=
up[i] * (-
gun_z->value);
381 void SV_AddBlend(
float r,
float g,
float b,
float a,
float *v_blend)
387 a2 = v_blend[3] + (1 - v_blend[3]) * a;
388 a3 = v_blend[3] / a2;
390 v_blend[0] = v_blend[0] * a3 + r * (1 - a3);
391 v_blend[1] = v_blend[1] * a3 + g * (1 - a3);
392 v_blend[2] = v_blend[2] * a3 + b * (1 - a3);
408 ent->client->ps.blend[0] = ent->client->ps.blend[1] =
409 ent->client->ps.blend[2] = ent->client->ps.blend[3] = 0;
412 VectorAdd(ent->s.origin, ent->client->ps.viewoffset, vieworg);
413 contents =
gi.pointcontents(vieworg);
415 if (contents & (CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA))
416 ent->client->ps.rdflags |= RDF_UNDERWATER;
418 ent->client->ps.rdflags &= ~RDF_UNDERWATER;
420 if (contents & (CONTENTS_SOLID | CONTENTS_LAVA))
421 SV_AddBlend(1.0, 0.3, 0.0, 0.6, ent->client->ps.blend);
422 else if (contents & CONTENTS_SLIME)
423 SV_AddBlend(0.0, 0.1, 0.05, 0.6, ent->client->ps.blend);
424 else if (contents & CONTENTS_WATER)
425 SV_AddBlend(0.5, 0.3, 0.2, 0.4, ent->client->ps.blend);
431 gi.sound(ent, CHAN_ITEM,
gi.soundindex(
"items/damage2.wav"), 1, ATTN_NORM, 0);
432 if (remaining > 30 || (remaining & 4))
434 }
else if (ent->client->invincible_framenum >
level.
framenum) {
435 remaining = ent->client->invincible_framenum -
level.
framenum;
437 gi.sound(ent, CHAN_ITEM,
gi.soundindex(
"items/protect2.wav"), 1, ATTN_NORM, 0);
438 if (remaining > 30 || (remaining & 4))
443 gi.sound(ent, CHAN_ITEM,
gi.soundindex(
"items/airout.wav"), 1, ATTN_NORM, 0);
444 if (remaining > 30 || (remaining & 4))
446 }
else if (ent->client->breather_framenum >
level.
framenum) {
449 gi.sound(ent, CHAN_ITEM,
gi.soundindex(
"items/airout.wav"), 1, ATTN_NORM, 0);
450 if (remaining > 30 || (remaining & 4))
451 SV_AddBlend(0.4, 1, 0.4, 0.04, ent->client->ps.blend);
455 if (ent->client->damage_alpha > 0)
456 SV_AddBlend(ent->client->damage_blend[0], ent->client->damage_blend[1]
457 , ent->client->damage_blend[2], ent->client->damage_alpha, ent->client->ps.blend);
459 if (ent->client->bonus_alpha > 0)
460 SV_AddBlend(0.85, 0.7, 0.3, ent->client->bonus_alpha, ent->client->ps.blend);
463 ent->client->damage_alpha -= 0.06;
464 if (ent->client->damage_alpha < 0)
465 ent->client->damage_alpha = 0;
468 ent->client->bonus_alpha -= 0.1;
469 if (ent->client->bonus_alpha < 0)
470 ent->client->bonus_alpha = 0;
485 if (ent->s.modelindex != 255)
491 if ((ent->client->oldvelocity[2] < 0) && (ent->velocity[2] > ent->client->oldvelocity[2]) && (!ent->groundentity)) {
492 delta = ent->client->oldvelocity[2];
494 if (!ent->groundentity)
496 delta = ent->velocity[2] - ent->client->oldvelocity[2];
498 delta = delta * delta * 0.0001;
501 if (ent->waterlevel == 3)
503 if (ent->waterlevel == 2)
505 if (ent->waterlevel == 1)
512 ent->s.event = EV_FOOTSTEP;
516 ent->client->fall_value = delta * 0.5;
517 if (ent->client->fall_value > 40)
518 ent->client->fall_value = 40;
522 if (ent->health > 0) {
524 ent->s.event = EV_FALLFAR;
526 ent->s.event = EV_FALL;
529 damage = (delta - 30) / 2;
532 VectorSet(dir, 0, 0, 1);
537 ent->s.event = EV_FALLSHORT;
553 int waterlevel, old_waterlevel;
570 if (!old_waterlevel && waterlevel) {
573 gi.sound(
current_player, CHAN_BODY,
gi.soundindex(
"player/lava_in.wav"), 1, ATTN_NORM, 0);
575 gi.sound(
current_player, CHAN_BODY,
gi.soundindex(
"player/watr_in.wav"), 1, ATTN_NORM, 0);
577 gi.sound(
current_player, CHAN_BODY,
gi.soundindex(
"player/watr_in.wav"), 1, ATTN_NORM, 0);
587 if (old_waterlevel && ! waterlevel) {
589 gi.sound(
current_player, CHAN_BODY,
gi.soundindex(
"player/watr_out.wav"), 1, ATTN_NORM, 0);
596 if (old_waterlevel != 3 && waterlevel == 3) {
597 gi.sound(
current_player, CHAN_BODY,
gi.soundindex(
"player/watr_un.wav"), 1, ATTN_NORM, 0);
603 if (old_waterlevel == 3 && waterlevel != 3) {
606 gi.sound(
current_player, CHAN_VOICE,
gi.soundindex(
"player/gasp1.wav"), 1, ATTN_NORM, 0);
610 gi.sound(
current_player, CHAN_VOICE,
gi.soundindex(
"player/gasp2.wav"), 1, ATTN_NORM, 0);
617 if (waterlevel == 3) {
619 if (breather || envirosuit) {
624 gi.sound(
current_player, CHAN_AUTO,
gi.soundindex(
"player/u_breath1.wav"), 1, ATTN_NORM, 0);
626 gi.sound(
current_player, CHAN_AUTO,
gi.soundindex(
"player/u_breath2.wav"), 1, ATTN_NORM, 0);
647 gi.sound(
current_player, CHAN_VOICE,
gi.soundindex(
"player/drown1.wav"), 1, ATTN_NORM, 0);
666 if (waterlevel && (
current_player->watertype & (CONTENTS_LAVA | CONTENTS_SLIME))) {
672 gi.sound(
current_player, CHAN_VOICE,
gi.soundindex(
"player/burn1.wav"), 1, ATTN_NORM, 0);
674 gi.sound(
current_player, CHAN_VOICE,
gi.soundindex(
"player/burn2.wav"), 1, ATTN_NORM, 0);
713 ent->s.effects |= EF_POWERSCREEN;
715 ent->s.effects |= EF_COLOR_SHELL;
716 ent->s.renderfx |= RF_SHELL_GREEN;
722 if (remaining > 30 || (remaining & 4))
723 ent->s.effects |= EF_QUAD;
727 remaining = ent->client->invincible_framenum -
level.
framenum;
728 if (remaining > 30 || (remaining & 4))
729 ent->s.effects |= EF_PENT;
734 ent->s.effects |= EF_COLOR_SHELL;
735 ent->s.renderfx |= (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE);
750 if (ent->groundentity &&
xyspeed > 225) {
752 ent->s.event = EV_FOOTSTEP;
767 ent->client->pers.helpchanged = 1;
771 if (ent->client->pers.helpchanged && ent->client->pers.helpchanged <= 1 && !(
level.
framenum & 63)) {
772 ent->client->pers.helpchanged++;
773 gi.sound(ent, CHAN_VOICE,
gi.soundindex(
"misc/pc_up.wav"), 1, ATTN_STATIC, 0);
777 if (ent->client->pers.weapon)
778 weap = ent->client->pers.weapon->classname;
782 if (ent->waterlevel && (ent->watertype & (CONTENTS_LAVA | CONTENTS_SLIME)))
784 else if (strcmp(weap,
"weapon_railgun") == 0)
785 ent->s.sound =
gi.soundindex(
"weapons/rg_hum.wav");
786 else if (strcmp(weap,
"weapon_bfg") == 0)
787 ent->s.sound =
gi.soundindex(
"weapons/bfg_hum.wav");
788 else if (ent->client->weapon_sound)
789 ent->s.sound = ent->client->weapon_sound;
804 if (ent->s.modelindex != 255)
807 client = ent->client;
809 if (client->ps.pmove.pm_flags & PMF_DUCKED)
819 if (duck != client->anim_duck && client->anim_priority <
ANIM_DEATH)
821 if (run != client->anim_run && client->anim_priority ==
ANIM_BASIC)
823 if (!ent->groundentity && client->anim_priority <=
ANIM_WAVE)
827 if (ent->s.frame > client->anim_end) {
831 }
else if (ent->s.frame < client->anim_end) {
839 if (client->anim_priority ==
ANIM_JUMP) {
840 if (!ent->groundentity)
851 client->anim_duck = duck;
852 client->anim_run = run;
854 if (!ent->groundentity) {
905 for (i = 0 ; i < 3 ; i++) {
931 if (ent->client->v_angle[PITCH] > 180)
932 ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH]) / 3;
934 ent->s.angles[PITCH] = ent->client->v_angle[PITCH] / 3;
935 ent->s.angles[YAW] = ent->client->v_angle[YAW];
936 ent->s.angles[ROLL] = 0;
937 ent->s.angles[ROLL] =
SV_CalcRoll(ent->s.angles, ent->velocity) * 4;
943 xyspeed = sqrt(ent->velocity[0] * ent->velocity[0] + ent->velocity[1] * ent->velocity[1]);
948 }
else if (ent->groundentity) {
986 if (ent->client->resp.spectator)
1000 VectorCopy(ent->velocity, ent->client->oldvelocity);
1001 VectorCopy(ent->client->ps.viewangles, ent->client->oldviewangles);
1004 VectorClear(ent->client->kick_origin);
1005 VectorClear(ent->client->kick_angles);
1010 gi.unicast(ent, qfalse);