Quake II RTX doxygen  1.0 dev
p_view.c File Reference
#include "g_local.h"
#include "m_player.h"

Go to the source code of this file.

Functions

float SV_CalcRoll (vec3_t angles, vec3_t velocity)
 
void P_DamageFeedback (edict_t *player)
 
void SV_CalcViewOffset (edict_t *ent)
 
void SV_CalcGunOffset (edict_t *ent)
 
void SV_AddBlend (float r, float g, float b, float a, float *v_blend)
 
void SV_CalcBlend (edict_t *ent)
 
void P_FallingDamage (edict_t *ent)
 
void P_WorldEffects (void)
 
void G_SetClientEffects (edict_t *ent)
 
void G_SetClientEvent (edict_t *ent)
 
void G_SetClientSound (edict_t *ent)
 
void G_SetClientFrame (edict_t *ent)
 
void ClientEndServerFrame (edict_t *ent)
 

Variables

static edict_t * current_player
 
static gclient_t * current_client
 
static vec3_t forward
 
static vec3_t right
 
static vec3_t up
 
float xyspeed
 
float bobmove
 
int bobcycle
 
float bobfracsin
 

Function Documentation

◆ ClientEndServerFrame()

void ClientEndServerFrame ( edict_t *  ent)

Definition at line 889 of file p_view.c.

890 {
891  float bobtime;
892  int i;
893 
894  current_player = ent;
895  current_client = ent->client;
896 
897  //
898  // If the origin or velocity have changed since ClientThink(),
899  // update the pmove values. This will happen when the client
900  // is pushed by a bmodel or kicked by an explosion.
901  //
902  // If it wasn't updated here, the view position would lag a frame
903  // behind the body position when pushed -- "sinking into plats"
904  //
905  for (i = 0 ; i < 3 ; i++) {
906  current_client->ps.pmove.origin[i] = ent->s.origin[i] * 8.0;
907  current_client->ps.pmove.velocity[i] = ent->velocity[i] * 8.0;
908  }
909 
910  //
911  // If the end of unit layout is displayed, don't give
912  // the player any normal movement attributes
913  //
914  if (level.intermissiontime) {
915  // FIXME: add view drifting here?
916  current_client->ps.blend[3] = 0;
917  current_client->ps.fov = 90;
918  G_SetStats(ent);
919  return;
920  }
921 
922  AngleVectors(ent->client->v_angle, forward, right, up);
923 
924  // burn from lava, etc
925  P_WorldEffects();
926 
927  //
928  // set model angles from view angles so other things in
929  // the world can tell which direction you are looking
930  //
931  if (ent->client->v_angle[PITCH] > 180)
932  ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH]) / 3;
933  else
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;
938 
939  //
940  // calculate speed and cycle to be used for
941  // all cyclic walking effects
942  //
943  xyspeed = sqrt(ent->velocity[0] * ent->velocity[0] + ent->velocity[1] * ent->velocity[1]);
944 
945  if (xyspeed < 5) {
946  bobmove = 0;
947  current_client->bobtime = 0; // start at beginning of cycle again
948  } else if (ent->groundentity) {
949  // so bobbing only cycles when on ground
950  if (xyspeed > 210)
951  bobmove = 0.25;
952  else if (xyspeed > 100)
953  bobmove = 0.125;
954  else
955  bobmove = 0.0625;
956  }
957 
958  bobtime = (current_client->bobtime += bobmove);
959 
960  if (current_client->ps.pmove.pm_flags & PMF_DUCKED)
961  bobtime *= 4;
962 
963  bobcycle = (int)bobtime;
964  bobfracsin = fabs(sin(bobtime * M_PI));
965 
966  // detect hitting the floor
967  P_FallingDamage(ent);
968 
969  // apply all the damage taken this frame
970  P_DamageFeedback(ent);
971 
972  // determine the view offsets
973  SV_CalcViewOffset(ent);
974 
975  // determine the gun offsets
976  SV_CalcGunOffset(ent);
977 
978  // determine the full screen color blend
979  // must be after viewoffset, so eye contents can be
980  // accurately determined
981  // FIXME: with client prediction, the contents
982  // should be determined by the client
983  SV_CalcBlend(ent);
984 
985  // chase cam stuff
986  if (ent->client->resp.spectator)
987  G_SetSpectatorStats(ent);
988  else
989  G_SetStats(ent);
990  G_CheckChaseStats(ent);
991 
992  G_SetClientEvent(ent);
993 
994  G_SetClientEffects(ent);
995 
996  G_SetClientSound(ent);
997 
998  G_SetClientFrame(ent);
999 
1000  VectorCopy(ent->velocity, ent->client->oldvelocity);
1001  VectorCopy(ent->client->ps.viewangles, ent->client->oldviewangles);
1002 
1003  // clear weapon kicks
1004  VectorClear(ent->client->kick_origin);
1005  VectorClear(ent->client->kick_angles);
1006 
1007  // if the scoreboard is up, update it
1008  if (ent->client->showscores && !(level.framenum & 31)) {
1009  DeathmatchScoreboardMessage(ent, ent->enemy);
1010  gi.unicast(ent, qfalse);
1011  }
1012 }

Referenced by ClientBegin(), ClientBeginDeathmatch(), and ClientEndServerFrames().

◆ G_SetClientEffects()

void G_SetClientEffects ( edict_t *  ent)

Definition at line 699 of file p_view.c.

700 {
701  int pa_type;
702  int remaining;
703 
704  ent->s.effects = 0;
705  ent->s.renderfx = 0;
706 
707  if (ent->health <= 0 || level.intermissiontime)
708  return;
709 
710  if (ent->powerarmor_time > level.time) {
711  pa_type = PowerArmorType(ent);
712  if (pa_type == POWER_ARMOR_SCREEN) {
713  ent->s.effects |= EF_POWERSCREEN;
714  } else if (pa_type == POWER_ARMOR_SHIELD) {
715  ent->s.effects |= EF_COLOR_SHELL;
716  ent->s.renderfx |= RF_SHELL_GREEN;
717  }
718  }
719 
720  if (ent->client->quad_framenum > level.framenum) {
721  remaining = ent->client->quad_framenum - level.framenum;
722  if (remaining > 30 || (remaining & 4))
723  ent->s.effects |= EF_QUAD;
724  }
725 
726  if (ent->client->invincible_framenum > level.framenum) {
727  remaining = ent->client->invincible_framenum - level.framenum;
728  if (remaining > 30 || (remaining & 4))
729  ent->s.effects |= EF_PENT;
730  }
731 
732  // show cheaters!!!
733  if (ent->flags & FL_GODMODE) {
734  ent->s.effects |= EF_COLOR_SHELL;
735  ent->s.renderfx |= (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE);
736  }
737 }

Referenced by ClientEndServerFrame().

◆ G_SetClientEvent()

void G_SetClientEvent ( edict_t *  ent)

Definition at line 745 of file p_view.c.

746 {
747  if (ent->s.event)
748  return;
749 
750  if (ent->groundentity && xyspeed > 225) {
751  if ((int)(current_client->bobtime + bobmove) != bobcycle)
752  ent->s.event = EV_FOOTSTEP;
753  }
754 }

Referenced by ClientEndServerFrame().

◆ G_SetClientFrame()

void G_SetClientFrame ( edict_t *  ent)

Definition at line 799 of file p_view.c.

800 {
801  gclient_t *client;
802  qboolean duck, run;
803 
804  if (ent->s.modelindex != 255)
805  return; // not in the player model
806 
807  client = ent->client;
808 
809  if (client->ps.pmove.pm_flags & PMF_DUCKED)
810  duck = qtrue;
811  else
812  duck = qfalse;
813  if (xyspeed)
814  run = qtrue;
815  else
816  run = qfalse;
817 
818  // check for stand/duck and stop/go transitions
819  if (duck != client->anim_duck && client->anim_priority < ANIM_DEATH)
820  goto newanim;
821  if (run != client->anim_run && client->anim_priority == ANIM_BASIC)
822  goto newanim;
823  if (!ent->groundentity && client->anim_priority <= ANIM_WAVE)
824  goto newanim;
825 
826  if (client->anim_priority == ANIM_REVERSE) {
827  if (ent->s.frame > client->anim_end) {
828  ent->s.frame--;
829  return;
830  }
831  } else if (ent->s.frame < client->anim_end) {
832  // continue an animation
833  ent->s.frame++;
834  return;
835  }
836 
837  if (client->anim_priority == ANIM_DEATH)
838  return; // stay there
839  if (client->anim_priority == ANIM_JUMP) {
840  if (!ent->groundentity)
841  return; // stay there
842  ent->client->anim_priority = ANIM_WAVE;
843  ent->s.frame = FRAME_jump3;
844  ent->client->anim_end = FRAME_jump6;
845  return;
846  }
847 
848 newanim:
849  // return to either a running or standing frame
850  client->anim_priority = ANIM_BASIC;
851  client->anim_duck = duck;
852  client->anim_run = run;
853 
854  if (!ent->groundentity) {
855  client->anim_priority = ANIM_JUMP;
856  if (ent->s.frame != FRAME_jump2)
857  ent->s.frame = FRAME_jump1;
858  client->anim_end = FRAME_jump2;
859  } else if (run) {
860  // running
861  if (duck) {
862  ent->s.frame = FRAME_crwalk1;
863  client->anim_end = FRAME_crwalk6;
864  } else {
865  ent->s.frame = FRAME_run1;
866  client->anim_end = FRAME_run6;
867  }
868  } else {
869  // standing
870  if (duck) {
871  ent->s.frame = FRAME_crstnd01;
872  client->anim_end = FRAME_crstnd19;
873  } else {
874  ent->s.frame = FRAME_stand01;
875  client->anim_end = FRAME_stand40;
876  }
877  }
878 }

Referenced by ClientEndServerFrame().

◆ G_SetClientSound()

void G_SetClientSound ( edict_t *  ent)

Definition at line 761 of file p_view.c.

762 {
763  char *weap;
764 
765  if (ent->client->pers.game_helpchanged != game.helpchanged) {
766  ent->client->pers.game_helpchanged = game.helpchanged;
767  ent->client->pers.helpchanged = 1;
768  }
769 
770  // help beep (no more than ONE time - that's annoying enough)
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);
774  }
775 
776 
777  if (ent->client->pers.weapon)
778  weap = ent->client->pers.weapon->classname;
779  else
780  weap = "";
781 
782  if (ent->waterlevel && (ent->watertype & (CONTENTS_LAVA | CONTENTS_SLIME)))
783  ent->s.sound = snd_fry;
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;
790  else
791  ent->s.sound = 0;
792 }

Referenced by ClientEndServerFrame().

◆ P_DamageFeedback()

void P_DamageFeedback ( edict_t *  player)

Definition at line 69 of file p_view.c.

70 {
71  gclient_t *client;
72  float side;
73  float realcount, count, kick;
74  vec3_t v;
75  int r, l;
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};
79 
80  client = player->client;
81 
82  // flash the backgrounds behind the status numbers
83  client->ps.stats[STAT_FLASHES] = 0;
84  if (client->damage_blood)
85  client->ps.stats[STAT_FLASHES] |= 1;
86  if (client->damage_armor && !(player->flags & FL_GODMODE) && (client->invincible_framenum <= level.framenum))
87  client->ps.stats[STAT_FLASHES] |= 2;
88 
89  // total points of damage shot at the player this frame
90  count = (client->damage_blood + client->damage_armor + client->damage_parmor);
91  if (count == 0)
92  return; // didn't take any damage
93 
94  // start a pain animation if still in the player model
95  if (client->anim_priority < ANIM_PAIN && player->s.modelindex == 255) {
96  static int i;
97 
98  client->anim_priority = ANIM_PAIN;
99  if (client->ps.pmove.pm_flags & PMF_DUCKED) {
100  player->s.frame = FRAME_crpain1 - 1;
101  client->anim_end = FRAME_crpain4;
102  } else {
103  i = (i + 1) % 3;
104  switch (i) {
105  case 0:
106  player->s.frame = FRAME_pain101 - 1;
107  client->anim_end = FRAME_pain104;
108  break;
109  case 1:
110  player->s.frame = FRAME_pain201 - 1;
111  client->anim_end = FRAME_pain204;
112  break;
113  case 2:
114  player->s.frame = FRAME_pain301 - 1;
115  client->anim_end = FRAME_pain304;
116  break;
117  }
118  }
119  }
120 
121  realcount = count;
122  if (count < 10)
123  count = 10; // always make a visible effect
124 
125  // play an apropriate pain sound
126  if ((level.time > player->pain_debounce_time) && !(player->flags & FL_GODMODE) && (client->invincible_framenum <= level.framenum)) {
127  r = 1 + (rand() & 1);
128  player->pain_debounce_time = level.time + 0.7;
129  if (player->health < 25)
130  l = 25;
131  else if (player->health < 50)
132  l = 50;
133  else if (player->health < 75)
134  l = 75;
135  else
136  l = 100;
137  gi.sound(player, CHAN_VOICE, gi.soundindex(va("*pain%i_%i.wav", l, r)), 1, ATTN_NORM, 0);
138  }
139 
140  // the total alpha of the blend is always proportional to count
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; // don't go too saturated
148 
149  // the color of the blend will vary based on how much was absorbed
150  // by different armors
151  VectorClear(v);
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);
159 
160 
161  //
162  // calculate view angle kicks
163  //
164  kick = abs(client->damage_knockback);
165  if (kick && player->health > 0) { // kick of 0 means no view adjust at all
166  kick = kick * 100 / player->health;
167 
168  if (kick < count * 0.5)
169  kick = count * 0.5;
170  if (kick > 50)
171  kick = 50;
172 
173  VectorSubtract(client->damage_from, player->s.origin, v);
174  VectorNormalize(v);
175 
176  side = DotProduct(v, right);
177  client->v_dmg_roll = kick * side * 0.3;
178 
179  side = -DotProduct(v, forward);
180  client->v_dmg_pitch = kick * side * 0.3;
181 
182  client->v_dmg_time = level.time + DAMAGE_TIME;
183  }
184 
185  //
186  // clear totals
187  //
188  client->damage_blood = 0;
189  client->damage_armor = 0;
190  client->damage_parmor = 0;
191  client->damage_knockback = 0;
192 }

Referenced by ClientEndServerFrame().

◆ P_FallingDamage()

void P_FallingDamage ( edict_t *  ent)

Definition at line 479 of file p_view.c.

480 {
481  float delta;
482  int damage;
483  vec3_t dir;
484 
485  if (ent->s.modelindex != 255)
486  return; // not in the player model
487 
488  if (ent->movetype == MOVETYPE_NOCLIP)
489  return;
490 
491  if ((ent->client->oldvelocity[2] < 0) && (ent->velocity[2] > ent->client->oldvelocity[2]) && (!ent->groundentity)) {
492  delta = ent->client->oldvelocity[2];
493  } else {
494  if (!ent->groundentity)
495  return;
496  delta = ent->velocity[2] - ent->client->oldvelocity[2];
497  }
498  delta = delta * delta * 0.0001;
499 
500  // never take falling damage if completely underwater
501  if (ent->waterlevel == 3)
502  return;
503  if (ent->waterlevel == 2)
504  delta *= 0.25;
505  if (ent->waterlevel == 1)
506  delta *= 0.5;
507 
508  if (delta < 1)
509  return;
510 
511  if (delta < 15) {
512  ent->s.event = EV_FOOTSTEP;
513  return;
514  }
515 
516  ent->client->fall_value = delta * 0.5;
517  if (ent->client->fall_value > 40)
518  ent->client->fall_value = 40;
519  ent->client->fall_time = level.time + FALL_TIME;
520 
521  if (delta > 30) {
522  if (ent->health > 0) {
523  if (delta >= 55)
524  ent->s.event = EV_FALLFAR;
525  else
526  ent->s.event = EV_FALL;
527  }
528  ent->pain_debounce_time = level.time; // no normal pain sound
529  damage = (delta - 30) / 2;
530  if (damage < 1)
531  damage = 1;
532  VectorSet(dir, 0, 0, 1);
533 
534  if (!deathmatch->value || !((int)dmflags->value & DF_NO_FALLING))
535  T_Damage(ent, world, world, dir, ent->s.origin, vec3_origin, damage, 0, 0, MOD_FALLING);
536  } else {
537  ent->s.event = EV_FALLSHORT;
538  return;
539  }
540 }

Referenced by ClientEndServerFrame().

◆ P_WorldEffects()

void P_WorldEffects ( void  )

Definition at line 549 of file p_view.c.

550 {
551  qboolean breather;
552  qboolean envirosuit;
553  int waterlevel, old_waterlevel;
554 
555  if (current_player->movetype == MOVETYPE_NOCLIP) {
556  current_player->air_finished = level.time + 12; // don't need air
557  return;
558  }
559 
560  waterlevel = current_player->waterlevel;
561  old_waterlevel = current_client->old_waterlevel;
562  current_client->old_waterlevel = waterlevel;
563 
564  breather = current_client->breather_framenum > level.framenum;
565  envirosuit = current_client->enviro_framenum > level.framenum;
566 
567  //
568  // if just entered a water volume, play a sound
569  //
570  if (!old_waterlevel && waterlevel) {
572  if (current_player->watertype & CONTENTS_LAVA)
573  gi.sound(current_player, CHAN_BODY, gi.soundindex("player/lava_in.wav"), 1, ATTN_NORM, 0);
574  else if (current_player->watertype & CONTENTS_SLIME)
575  gi.sound(current_player, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0);
576  else if (current_player->watertype & CONTENTS_WATER)
577  gi.sound(current_player, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0);
578  current_player->flags |= FL_INWATER;
579 
580  // clear damage_debounce, so the pain sound will play immediately
581  current_player->damage_debounce_time = level.time - 1;
582  }
583 
584  //
585  // if just completely exited a water volume, play a sound
586  //
587  if (old_waterlevel && ! waterlevel) {
589  gi.sound(current_player, CHAN_BODY, gi.soundindex("player/watr_out.wav"), 1, ATTN_NORM, 0);
590  current_player->flags &= ~FL_INWATER;
591  }
592 
593  //
594  // check for head just going under water
595  //
596  if (old_waterlevel != 3 && waterlevel == 3) {
597  gi.sound(current_player, CHAN_BODY, gi.soundindex("player/watr_un.wav"), 1, ATTN_NORM, 0);
598  }
599 
600  //
601  // check for head just coming out of water
602  //
603  if (old_waterlevel == 3 && waterlevel != 3) {
604  if (current_player->air_finished < level.time) {
605  // gasp for air
606  gi.sound(current_player, CHAN_VOICE, gi.soundindex("player/gasp1.wav"), 1, ATTN_NORM, 0);
608  } else if (current_player->air_finished < level.time + 11) {
609  // just break surface
610  gi.sound(current_player, CHAN_VOICE, gi.soundindex("player/gasp2.wav"), 1, ATTN_NORM, 0);
611  }
612  }
613 
614  //
615  // check for drowning
616  //
617  if (waterlevel == 3) {
618  // breather or envirosuit give air
619  if (breather || envirosuit) {
620  current_player->air_finished = level.time + 10;
621 
622  if (((int)(current_client->breather_framenum - level.framenum) % 25) == 0) {
623  if (!current_client->breather_sound)
624  gi.sound(current_player, CHAN_AUTO, gi.soundindex("player/u_breath1.wav"), 1, ATTN_NORM, 0);
625  else
626  gi.sound(current_player, CHAN_AUTO, gi.soundindex("player/u_breath2.wav"), 1, ATTN_NORM, 0);
627  current_client->breather_sound ^= 1;
629  //FIXME: release a bubble?
630  }
631  }
632 
633  // if out of air, start drowning
634  if (current_player->air_finished < level.time) {
635  // drown!
636  if (current_player->client->next_drown_time < level.time
637  && current_player->health > 0) {
638  current_player->client->next_drown_time = level.time + 1;
639 
640  // take more damage the longer underwater
641  current_player->dmg += 2;
642  if (current_player->dmg > 15)
643  current_player->dmg = 15;
644 
645  // play a gurp sound instead of a normal pain sound
646  if (current_player->health <= current_player->dmg)
647  gi.sound(current_player, CHAN_VOICE, gi.soundindex("player/drown1.wav"), 1, ATTN_NORM, 0);
648  else if (rand() & 1)
649  gi.sound(current_player, CHAN_VOICE, gi.soundindex("*gurp1.wav"), 1, ATTN_NORM, 0);
650  else
651  gi.sound(current_player, CHAN_VOICE, gi.soundindex("*gurp2.wav"), 1, ATTN_NORM, 0);
652 
653  current_player->pain_debounce_time = level.time;
654 
656  }
657  }
658  } else {
659  current_player->air_finished = level.time + 12;
660  current_player->dmg = 2;
661  }
662 
663  //
664  // check for sizzle damage
665  //
666  if (waterlevel && (current_player->watertype & (CONTENTS_LAVA | CONTENTS_SLIME))) {
667  if (current_player->watertype & CONTENTS_LAVA) {
668  if (current_player->health > 0
669  && current_player->pain_debounce_time <= level.time
670  && current_client->invincible_framenum < level.framenum) {
671  if (rand() & 1)
672  gi.sound(current_player, CHAN_VOICE, gi.soundindex("player/burn1.wav"), 1, ATTN_NORM, 0);
673  else
674  gi.sound(current_player, CHAN_VOICE, gi.soundindex("player/burn2.wav"), 1, ATTN_NORM, 0);
675  current_player->pain_debounce_time = level.time + 1;
676  }
677 
678  if (envirosuit) // take 1/3 damage with envirosuit
679  T_Damage(current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 1 * waterlevel, 0, 0, MOD_LAVA);
680  else
681  T_Damage(current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 3 * waterlevel, 0, 0, MOD_LAVA);
682  }
683 
684  if (current_player->watertype & CONTENTS_SLIME) {
685  if (!envirosuit) {
686  // no damage from slime with envirosuit
687  T_Damage(current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 1 * waterlevel, 0, 0, MOD_SLIME);
688  }
689  }
690  }
691 }

Referenced by ClientEndServerFrame().

◆ SV_AddBlend()

void SV_AddBlend ( float  r,
float  g,
float  b,
float  a,
float *  v_blend 
)

Definition at line 381 of file p_view.c.

382 {
383  float a2, a3;
384 
385  if (a <= 0)
386  return;
387  a2 = v_blend[3] + (1 - v_blend[3]) * a; // new total alpha
388  a3 = v_blend[3] / a2; // fraction of color from old
389 
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);
393  v_blend[3] = a2;
394 }

Referenced by SV_CalcBlend().

◆ SV_CalcBlend()

void SV_CalcBlend ( edict_t *  ent)

Definition at line 402 of file p_view.c.

403 {
404  int contents;
405  vec3_t vieworg;
406  int remaining;
407 
408  ent->client->ps.blend[0] = ent->client->ps.blend[1] =
409  ent->client->ps.blend[2] = ent->client->ps.blend[3] = 0;
410 
411  // add for contents
412  VectorAdd(ent->s.origin, ent->client->ps.viewoffset, vieworg);
413  contents = gi.pointcontents(vieworg);
414 
415  if (contents & (CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA))
416  ent->client->ps.rdflags |= RDF_UNDERWATER;
417  else
418  ent->client->ps.rdflags &= ~RDF_UNDERWATER;
419 
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);
426 
427  // add for powerups
428  if (ent->client->quad_framenum > level.framenum) {
429  remaining = ent->client->quad_framenum - level.framenum;
430  if (remaining == 30) // beginning to fade
431  gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage2.wav"), 1, ATTN_NORM, 0);
432  if (remaining > 30 || (remaining & 4))
433  SV_AddBlend(0, 0, 1, 0.08, ent->client->ps.blend);
434  } else if (ent->client->invincible_framenum > level.framenum) {
435  remaining = ent->client->invincible_framenum - level.framenum;
436  if (remaining == 30) // beginning to fade
437  gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect2.wav"), 1, ATTN_NORM, 0);
438  if (remaining > 30 || (remaining & 4))
439  SV_AddBlend(1, 1, 0, 0.08, ent->client->ps.blend);
440  } else if (ent->client->enviro_framenum > level.framenum) {
441  remaining = ent->client->enviro_framenum - level.framenum;
442  if (remaining == 30) // beginning to fade
443  gi.sound(ent, CHAN_ITEM, gi.soundindex("items/airout.wav"), 1, ATTN_NORM, 0);
444  if (remaining > 30 || (remaining & 4))
445  SV_AddBlend(0, 1, 0, 0.08, ent->client->ps.blend);
446  } else if (ent->client->breather_framenum > level.framenum) {
447  remaining = ent->client->breather_framenum - level.framenum;
448  if (remaining == 30) // beginning to fade
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);
452  }
453 
454  // add for damage
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);
458 
459  if (ent->client->bonus_alpha > 0)
460  SV_AddBlend(0.85, 0.7, 0.3, ent->client->bonus_alpha, ent->client->ps.blend);
461 
462  // drop the damage value
463  ent->client->damage_alpha -= 0.06;
464  if (ent->client->damage_alpha < 0)
465  ent->client->damage_alpha = 0;
466 
467  // drop the bonus value
468  ent->client->bonus_alpha -= 0.1;
469  if (ent->client->bonus_alpha < 0)
470  ent->client->bonus_alpha = 0;
471 }

Referenced by ClientEndServerFrame().

◆ SV_CalcGunOffset()

void SV_CalcGunOffset ( edict_t *  ent)

Definition at line 332 of file p_view.c.

333 {
334  int i;
335  float delta;
336 
337  // gun angles from bobbing
338  ent->client->ps.gunangles[ROLL] = xyspeed * bobfracsin * 0.005;
339  ent->client->ps.gunangles[YAW] = xyspeed * bobfracsin * 0.01;
340  if (bobcycle & 1) {
341  ent->client->ps.gunangles[ROLL] = -ent->client->ps.gunangles[ROLL];
342  ent->client->ps.gunangles[YAW] = -ent->client->ps.gunangles[YAW];
343  }
344 
345  ent->client->ps.gunangles[PITCH] = xyspeed * bobfracsin * 0.005;
346 
347  // gun angles from delta movement
348  for (i = 0 ; i < 3 ; i++) {
349  delta = ent->client->oldviewangles[i] - ent->client->ps.viewangles[i];
350  if (delta > 180)
351  delta -= 360;
352  if (delta < -180)
353  delta += 360;
354  if (delta > 45)
355  delta = 45;
356  if (delta < -45)
357  delta = -45;
358  if (i == YAW)
359  ent->client->ps.gunangles[ROLL] += 0.1 * delta;
360  ent->client->ps.gunangles[i] += 0.2 * delta;
361  }
362 
363  // gun height
364  VectorClear(ent->client->ps.gunoffset);
365 // ent->ps->gunorigin[2] += bob;
366 
367  // gun_x / gun_y / gun_z are development tools
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);
372  }
373 }

Referenced by ClientEndServerFrame().

◆ SV_CalcRoll()

float SV_CalcRoll ( vec3_t  angles,
vec3_t  velocity 
)

Definition at line 40 of file p_view.c.

41 {
42  float sign;
43  float side;
44  float value;
45 
46  side = DotProduct(velocity, right);
47  sign = side < 0 ? -1 : 1;
48  side = fabs(side);
49 
50  value = sv_rollangle->value;
51 
52  if (side < sv_rollspeed->value)
53  side = side * value / sv_rollspeed->value;
54  else
55  side = value;
56 
57  return side * sign;
58 
59 }

Referenced by ClientEndServerFrame().

◆ SV_CalcViewOffset()

void SV_CalcViewOffset ( edict_t *  ent)

Definition at line 213 of file p_view.c.

214 {
215  float *angles;
216  float bob;
217  float ratio;
218  float delta;
219  vec3_t v;
220 
221 
222 //===================================
223 
224  // base angles
225  angles = ent->client->ps.kick_angles;
226 
227  // if dead, fix the angle and don't add any kick
228  if (ent->deadflag) {
229  VectorClear(angles);
230 
231  ent->client->ps.viewangles[ROLL] = 40;
232  ent->client->ps.viewangles[PITCH] = -15;
233  ent->client->ps.viewangles[YAW] = ent->client->killer_yaw;
234  } else {
235  // add angles based on weapon kick
236 
237  VectorCopy(ent->client->kick_angles, angles);
238 
239  // add angles based on damage kick
240 
241  ratio = (ent->client->v_dmg_time - level.time) / DAMAGE_TIME;
242  if (ratio < 0) {
243  ratio = 0;
244  ent->client->v_dmg_pitch = 0;
245  ent->client->v_dmg_roll = 0;
246  }
247  angles[PITCH] += ratio * ent->client->v_dmg_pitch;
248  angles[ROLL] += ratio * ent->client->v_dmg_roll;
249 
250  // add pitch based on fall kick
251 
252  ratio = (ent->client->fall_time - level.time) / FALL_TIME;
253  if (ratio < 0)
254  ratio = 0;
255  angles[PITCH] += ratio * ent->client->fall_value;
256 
257  // add angles based on velocity
258 
259  delta = DotProduct(ent->velocity, forward);
260  angles[PITCH] += delta * run_pitch->value;
261 
262  delta = DotProduct(ent->velocity, right);
263  angles[ROLL] += delta * run_roll->value;
264 
265  // add angles based on bob
266 
267  delta = bobfracsin * bob_pitch->value * xyspeed;
268  if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
269  delta *= 6; // crouching
270  angles[PITCH] += delta;
271  delta = bobfracsin * bob_roll->value * xyspeed;
272  if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
273  delta *= 6; // crouching
274  if (bobcycle & 1)
275  delta = -delta;
276  angles[ROLL] += delta;
277  }
278 
279 //===================================
280 
281  // base origin
282 
283  VectorClear(v);
284 
285  // add view height
286 
287  v[2] += ent->viewheight;
288 
289  // add fall height
290 
291  ratio = (ent->client->fall_time - level.time) / FALL_TIME;
292  if (ratio < 0)
293  ratio = 0;
294  v[2] -= ratio * ent->client->fall_value * 0.4;
295 
296  // add bob height
297 
298  bob = bobfracsin * xyspeed * bob_up->value;
299  if (bob > 6)
300  bob = 6;
301  //gi.DebugGraph (bob *2, 255);
302  v[2] += bob;
303 
304  // add kick offset
305 
306  VectorAdd(v, ent->client->kick_origin, v);
307 
308  // absolutely bound offsets
309  // so the view can never be outside the player box
310 
311  if (v[0] < -14)
312  v[0] = -14;
313  else if (v[0] > 14)
314  v[0] = 14;
315  if (v[1] < -14)
316  v[1] = -14;
317  else if (v[1] > 14)
318  v[1] = 14;
319  if (v[2] < -22)
320  v[2] = -22;
321  else if (v[2] > 30)
322  v[2] = 30;
323 
324  VectorCopy(v, ent->client->ps.viewoffset);
325 }

Referenced by ClientEndServerFrame().

Variable Documentation

◆ bobcycle

int bobcycle

◆ bobfracsin

float bobfracsin

Definition at line 32 of file p_view.c.

Referenced by ClientEndServerFrame(), SV_CalcGunOffset(), and SV_CalcViewOffset().

◆ bobmove

float bobmove

Definition at line 30 of file p_view.c.

Referenced by ClientEndServerFrame(), and G_SetClientEvent().

◆ current_client

gclient_t* current_client
static

Definition at line 25 of file p_view.c.

Referenced by ClientEndServerFrame(), G_SetClientEvent(), and P_WorldEffects().

◆ current_player

edict_t* current_player
static

Definition at line 24 of file p_view.c.

Referenced by ClientEndServerFrame(), and P_WorldEffects().

◆ forward

vec3_t forward
static

Definition at line 27 of file p_view.c.

Referenced by actorMachineGun(), AngleVectors(), Blaster_Fire(), boss2_firebullet_left(), boss2_firebullet_right(), Boss2Rocket(), Chaingun_Fire(), CheckPowerArmor(), ChickRocket(), CL_AddPacketEntities(), CL_BfgParticles(), CL_FlyParticles(), CL_Heatbeam(), CL_MuzzleFlash2(), CL_TrackerTrail(), ClientEndServerFrame(), CM_TransformedPointContents(), Drop_Item(), fire_flaregun(), fire_grenade(), fire_grenade2(), fire_hit(), fire_lead(), flare_sparks(), floater_fire_blaster(), floater_zap(), flyer_fire(), G_ProjectSource(), GL_SetupFrustum(), GladiatorGun(), GunnerFire(), GunnerGrenade(), hover_fire_blaster(), InfantryMachineGun(), infront(), jorg_firebullet_left(), jorg_firebullet_right(), jorgBFG(), Machinegun_Fire(), makronBFG(), MakronHyperblaster(), MakronRailgun(), medic_fire_blaster(), mutant_jump_takeoff(), MVD_HitPlayer(), P_DamageFeedback(), P_ProjectSource(), PM_DeadMove(), prepare_camera(), Prompt_CompleteHistory(), RotatedBBox(), soldier_fire(), SP_func_door_secret(), supertankMachineGun(), supertankRocket(), SV_CalcGunOffset(), SV_CalcViewOffset(), SV_Push(), TankBlaster(), TankMachineGun(), TankRocket(), Touch_Multi(), UpdateChaseCam(), UpdateTerrainShadowMapView(), vectoangles(), vkpt_freecam_update(), vkpt_physical_sky_update_ubo(), weapon_bfg_fire(), weapon_flaregun_fire(), weapon_grenade_fire(), weapon_grenadelauncher_fire(), weapon_railgun_fire(), Weapon_RocketLauncher_Fire(), weapon_shotgun_fire(), and weapon_supershotgun_fire().

◆ right

◆ up

◆ xyspeed

float xyspeed
gi
game_import_t gi
Definition: g_main.c:23
G_SetSpectatorStats
void G_SetSpectatorStats(edict_t *ent)
Definition: p_hud.c:504
deathmatch
cvar_t * deathmatch
Definition: g_main.c:33
FRAME_jump6
#define FRAME_jump6
Definition: m_player.h:93
run_roll
cvar_t * run_roll
Definition: g_main.c:61
FRAME_pain301
#define FRAME_pain301
Definition: m_actor.h:102
sv_rollspeed
cvar_t * sv_rollspeed
Definition: g_main.c:54
FRAME_crpain1
#define FRAME_crpain1
Definition: m_player.h:191
ANIM_DEATH
#define ANIM_DEATH
Definition: g_local.h:816
run_pitch
cvar_t * run_pitch
Definition: g_main.c:60
FRAME_run6
#define FRAME_run6
Definition: m_berserk.h:63
snd_fry
int snd_fry
Definition: g_main.c:28
bobfracsin
float bobfracsin
Definition: p_view.c:32
FRAME_stand01
#define FRAME_stand01
Definition: m_boss31.h:134
PowerArmorType
int PowerArmorType(edict_t *ent)
Definition: g_items.c:655
MOVETYPE_NOCLIP
@ MOVETYPE_NOCLIP
Definition: g_local.h:187
FRAME_jump2
#define FRAME_jump2
Definition: m_player.h:89
game_locals_t::helpchanged
int helpchanged
Definition: g_local.h:270
G_SetClientSound
void G_SetClientSound(edict_t *ent)
Definition: p_view.c:761
gun_x
cvar_t * gun_x
Definition: g_main.c:56
FRAME_pain304
#define FRAME_pain304
Definition: m_boss31.h:112
MOD_FALLING
#define MOD_FALLING
Definition: g_local.h:479
FRAME_jump3
#define FRAME_jump3
Definition: m_player.h:90
gun_y
cvar_t * gun_y
Definition: g_local.h:526
MOD_SLIME
#define MOD_SLIME
Definition: g_local.h:475
T_Damage
void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod)
Definition: g_combat.c:358
FRAME_pain101
#define FRAME_pain101
Definition: m_actor.h:96
FRAME_crstnd01
#define FRAME_crstnd01
Definition: m_player.h:157
FALL_TIME
#define FALL_TIME
Definition: g_local.h:47
ANIM_PAIN
#define ANIM_PAIN
Definition: g_local.h:814
SV_CalcGunOffset
void SV_CalcGunOffset(edict_t *ent)
Definition: p_view.c:332
ANIM_REVERSE
#define ANIM_REVERSE
Definition: g_local.h:817
G_SetStats
void G_SetStats(edict_t *ent)
Definition: p_hud.c:353
POWER_ARMOR_SHIELD
#define POWER_ARMOR_SHIELD
Definition: g_local.h:158
POWER_ARMOR_SCREEN
#define POWER_ARMOR_SCREEN
Definition: g_local.h:157
ANIM_BASIC
#define ANIM_BASIC
Definition: g_local.h:811
vec3_origin
vec3_t vec3_origin
Definition: shared.c:21
FL_INWATER
#define FL_INWATER
Definition: g_local.h:62
G_SetClientEffects
void G_SetClientEffects(edict_t *ent)
Definition: p_view.c:699
DAMAGE_TIME
#define DAMAGE_TIME
Definition: g_local.h:46
xyspeed
float xyspeed
Definition: p_view.c:28
SV_CalcRoll
float SV_CalcRoll(vec3_t angles, vec3_t velocity)
Definition: p_view.c:40
ANIM_JUMP
#define ANIM_JUMP
Definition: g_local.h:813
gun_z
cvar_t * gun_z
Definition: g_local.h:526
FRAME_jump1
#define FRAME_jump1
Definition: m_player.h:88
FRAME_pain204
#define FRAME_pain204
Definition: m_brain.h:134
forward
static vec3_t forward
Definition: p_view.c:27
SV_CalcViewOffset
void SV_CalcViewOffset(edict_t *ent)
Definition: p_view.c:213
FL_GODMODE
#define FL_GODMODE
Definition: g_local.h:63
va
char * va(const char *format,...)
Definition: shared.c:429
game
game_locals_t game
Definition: g_main.c:21
DeathmatchScoreboardMessage
void DeathmatchScoreboardMessage(edict_t *client, edict_t *killer)
Definition: p_hud.c:150
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: shared.c:23
bobcycle
int bobcycle
Definition: p_view.c:31
G_SetClientEvent
void G_SetClientEvent(edict_t *ent)
Definition: p_view.c:745
bob_up
cvar_t * bob_up
Definition: g_main.c:62
P_WorldEffects
void P_WorldEffects(void)
Definition: p_view.c:549
level_locals_t::framenum
int framenum
Definition: g_local.h:298
FRAME_crwalk1
#define FRAME_crwalk1
Definition: m_player.h:176
level_locals_t::time
float time
Definition: g_local.h:299
current_client
static gclient_t * current_client
Definition: p_view.c:25
level_locals_t::intermissiontime
float intermissiontime
Definition: g_local.h:306
FRAME_stand40
#define FRAME_stand40
Definition: m_boss2.h:32
bob_pitch
cvar_t * bob_pitch
Definition: g_main.c:63
world
#define world
Definition: g_local.h:550
up
static vec3_t up
Definition: p_view.c:27
PNOISE_SELF
#define PNOISE_SELF
Definition: g_local.h:179
bobmove
float bobmove
Definition: p_view.c:30
bob_roll
cvar_t * bob_roll
Definition: g_main.c:64
right
static vec3_t right
Definition: p_view.c:27
FRAME_run1
#define FRAME_run1
Definition: m_berserk.h:58
level
level_locals_t level
Definition: g_main.c:22
FRAME_crpain4
#define FRAME_crpain4
Definition: m_player.h:194
PlayerNoise
void PlayerNoise(edict_t *who, vec3_t where, int type)
Definition: p_weapon.c:56
sv_rollangle
cvar_t * sv_rollangle
Definition: g_main.c:55
FRAME_pain201
#define FRAME_pain201
Definition: m_actor.h:99
SV_AddBlend
void SV_AddBlend(float r, float g, float b, float a, float *v_blend)
Definition: p_view.c:381
P_DamageFeedback
void P_DamageFeedback(edict_t *player)
Definition: p_view.c:69
G_CheckChaseStats
void G_CheckChaseStats(edict_t *ent)
Definition: p_hud.c:485
ANIM_WAVE
#define ANIM_WAVE
Definition: g_local.h:812
dmflags
cvar_t * dmflags
Definition: g_main.c:35
current_player
static edict_t * current_player
Definition: p_view.c:24
int
CONST PIXELFORMATDESCRIPTOR int
Definition: wgl.c:26
FRAME_pain104
#define FRAME_pain104
Definition: m_brain.h:113
DAMAGE_NO_ARMOR
#define DAMAGE_NO_ARMOR
Definition: g_local.h:648
FRAME_crwalk6
#define FRAME_crwalk6
Definition: m_player.h:181
G_SetClientFrame
void G_SetClientFrame(edict_t *ent)
Definition: p_view.c:799
P_FallingDamage
void P_FallingDamage(edict_t *ent)
Definition: p_view.c:479
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: shared.c:55
MOD_LAVA
#define MOD_LAVA
Definition: g_local.h:476
MOD_WATER
#define MOD_WATER
Definition: g_local.h:474
SV_CalcBlend
void SV_CalcBlend(edict_t *ent)
Definition: p_view.c:402
FRAME_crstnd19
#define FRAME_crstnd19
Definition: m_player.h:175