Quake II RTX doxygen  1.0 dev
game.c File Reference
#include "client.h"

Go to the source code of this file.

Macros

#define PAGE_CLIENTS   16
 
#define VER_OFS   (272 - (int)(sizeof(VERSION_STRING) - 1) * CHAR_WIDTH)
 
#define MENU_ITEMS   10
 
#define YES   "\xD9\xE5\xF3"
 
#define NO   "\xCE\xEF"
 
#define DEFAULT   "\xC4\xE5\xE6\xE1\xF5\xEC\xF4"
 

Functions

static void MVD_UpdateClient (mvd_client_t *client)
 
static void MVD_LayoutClients (mvd_client_t *client)
 
static int MVD_CountClients (mvd_t *mvd)
 
static void MVD_LayoutChannels (mvd_client_t *client)
 
static int clamp_menu_cursor (mvd_client_t *client)
 
static void MVD_LayoutMenu (mvd_client_t *client)
 
static void MVD_LayoutScores (mvd_client_t *client)
 
static void MVD_LayoutFollow (mvd_client_t *client)
 
static void MVD_SetNewLayout (mvd_client_t *client, mvd_layout_t type)
 
static void MVD_SetDefaultLayout (mvd_client_t *client)
 
static void MVD_ToggleLayout (mvd_client_t *client, mvd_layout_t type)
 
static void MVD_SetFollowLayout (mvd_client_t *client)
 
static void MVD_UpdateLayouts (mvd_t *mvd)
 
static void write_cs_list (mvd_client_t *client, mvd_cs_t *cs)
 
static void MVD_FollowStop (mvd_client_t *client)
 
static void MVD_FollowStart (mvd_client_t *client, mvd_player_t *target)
 
static qboolean MVD_TestTarget (mvd_client_t *client, mvd_player_t *target)
 
static mvd_player_tMVD_FollowNext (mvd_client_t *client, mvd_player_t *from)
 
static mvd_player_tMVD_FollowPrev (mvd_client_t *client, mvd_player_t *from)
 
static mvd_player_tMVD_MostFollowed (mvd_t *mvd)
 
static void MVD_UpdateTarget (mvd_client_t *client)
 
void MVD_BroadcastPrintf (mvd_t *mvd, int level, int mask, const char *fmt,...)
 
static void MVD_SetServerState (client_t *cl, mvd_t *mvd)
 
void MVD_SwitchChannel (mvd_client_t *client, mvd_t *mvd)
 
static qboolean MVD_PartFilter (mvd_client_t *client)
 
static void MVD_TrySwitchChannel (mvd_client_t *client, mvd_t *mvd)
 
static void MVD_Admin_f (mvd_client_t *client)
 
static void MVD_Forward_f (mvd_client_t *client)
 
static void MVD_Say_f (mvd_client_t *client, int argnum)
 
static void MVD_Observe_f (mvd_client_t *client)
 
static mvd_player_tMVD_SetPlayer (mvd_client_t *client, const char *s)
 
static void MVD_Follow_f (mvd_client_t *client)
 
static qboolean count_chase_bits (mvd_client_t *client)
 
static void MVD_AutoFollow_f (mvd_client_t *client)
 
static void MVD_Invuse_f (mvd_client_t *client)
 
static void MVD_Join_f (mvd_client_t *client)
 
static void print_channel (client_t *cl, mvd_t *mvd)
 
static void mvd_channel_list_f (mvd_client_t *client)
 
static void MVD_Clients_f (mvd_client_t *client)
 
static void MVD_Commands_f (mvd_client_t *client)
 
static void MVD_GameClientCommand (edict_t *ent)
 
void MVD_FreePlayer (mvd_player_t *player)
 
static void reset_unicast_strings (mvd_t *mvd, int index)
 
static void set_player_name (mvd_t *mvd, int index)
 
static void update_player_name (mvd_t *mvd, int index)
 
void MVD_SetPlayerNames (mvd_t *mvd)
 
void MVD_UpdateConfigstring (mvd_t *mvd, int index)
 
void MVD_LinkEdict (mvd_t *mvd, edict_t *ent)
 
void MVD_RemoveClient (client_t *client)
 
static void MVD_GameInit (void)
 
static void MVD_GameShutdown (void)
 
static void MVD_GameSpawnEntities (const char *mapname, const char *entstring, const char *spawnpoint)
 
static void MVD_GameWriteGame (const char *filename, qboolean autosave)
 
static void MVD_GameReadGame (const char *filename)
 
static void MVD_GameWriteLevel (const char *filename)
 
static void MVD_GameReadLevel (const char *filename)
 
static qboolean MVD_GameClientConnect (edict_t *ent, char *userinfo)
 
static void MVD_GameClientBegin (edict_t *ent)
 
static void MVD_GameClientUserinfoChanged (edict_t *ent, char *userinfo)
 
void MVD_GameClientNameChanged (edict_t *ent, const char *name)
 
void MVD_GameClientDrop (edict_t *ent, const char *prefix, const char *reason)
 
static void MVD_GameClientDisconnect (edict_t *ent)
 
static mvd_player_tMVD_HitPlayer (mvd_client_t *client)
 
static trace_t q_gameabi MVD_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
 
static int MVD_PointContents (vec3_t p)
 
static void MVD_GameClientThink (edict_t *ent, usercmd_t *cmd)
 
static void MVD_IntermissionStart (mvd_t *mvd)
 
static void MVD_IntermissionStop (mvd_t *mvd)
 
static void MVD_NotifyClient (mvd_client_t *client)
 
void MVD_UpdateClients (mvd_t *mvd)
 
static void MVD_WriteDemoMessage (mvd_t *mvd)
 
static void MVD_GameRunFrame (void)
 
static void MVD_GameServerCommand (void)
 
void MVD_PrepWorldFrame (void)
 

Variables

static cvar_t * mvd_admin_password
 
static cvar_t * mvd_part_filter
 
static cvar_t * mvd_flood_msgs
 
static cvar_t * mvd_flood_persecond
 
static cvar_t * mvd_flood_waitdelay
 
static cvar_t * mvd_flood_mute
 
static cvar_t * mvd_filter_version
 
static cvar_t * mvd_stats_score
 
static cvar_t * mvd_stats_hack
 
static cvar_t * mvd_freeze_hack
 
static cvar_t * mvd_chase_prefix
 
mvd_client_tmvd_clients
 
mvd_player_t mvd_dummy
 
static int mvd_numplayers
 
game_export_t mvd_ge
 

Macro Definition Documentation

◆ DEFAULT

#define DEFAULT   "\xC4\xE5\xE6\xE1\xF5\xEC\xF4"

Definition at line 232 of file game.c.

◆ MENU_ITEMS

#define MENU_ITEMS   10

Definition at line 229 of file game.c.

◆ NO

#define NO   "\xCE\xEF"

Definition at line 231 of file game.c.

◆ PAGE_CLIENTS

#define PAGE_CLIENTS   16

Definition at line 54 of file game.c.

◆ VER_OFS

#define VER_OFS   (272 - (int)(sizeof(VERSION_STRING) - 1) * CHAR_WIDTH)

Definition at line 56 of file game.c.

◆ YES

#define YES   "\xD9\xE5\xF3"

Definition at line 230 of file game.c.

Function Documentation

◆ clamp_menu_cursor()

static int clamp_menu_cursor ( mvd_client_t client)
static

Definition at line 234 of file game.c.

235 {
236  if (client->layout_cursor < 0) {
237  client->layout_cursor = MENU_ITEMS - 1;
238  } else if (client->layout_cursor > MENU_ITEMS - 1) {
239  client->layout_cursor = 0;
240  }
241  return client->layout_cursor;
242 }

Referenced by MVD_Invuse_f(), and MVD_LayoutMenu().

◆ count_chase_bits()

static qboolean count_chase_bits ( mvd_client_t client)
static

Definition at line 1118 of file game.c.

1119 {
1120  mvd_t *mvd = client->mvd;
1121  int i, j, count = 0;
1122 
1123  for (i = 0; i < (mvd->maxclients + CHAR_BIT - 1) / CHAR_BIT; i++)
1124  if (client->chase_bitmap[i])
1125  for (j = 0; j < 8; j++)
1126  if (client->chase_bitmap[i] & (1 << j))
1127  count++;
1128 
1129  return count;
1130 }

Referenced by MVD_AutoFollow_f().

◆ MVD_Admin_f()

static void MVD_Admin_f ( mvd_client_t client)
static

Definition at line 837 of file game.c.

838 {
839  char *s = mvd_admin_password->string;
840 
841  if (client->admin) {
842  client->admin = qfalse;
843  SV_ClientPrintf(client->cl, PRINT_HIGH, "[MVD] Lost admin status.\n");
844  return;
845  }
846 
847  if (!NET_IsLocalAddress(&client->cl->netchan->remote_address)) {
848  if (Cmd_Argc() < 2) {
849  SV_ClientPrintf(client->cl, PRINT_HIGH, "Usage: %s <password>\n", Cmd_Argv(0));
850  return;
851  }
852  if (!s[0] || strcmp(s, Cmd_Argv(1))) {
853  SV_ClientPrintf(client->cl, PRINT_HIGH, "[MVD] Invalid password.\n");
854  return;
855  }
856  }
857 
858  client->admin = qtrue;
859  SV_ClientPrintf(client->cl, PRINT_HIGH, "[MVD] Granted admin status.\n");
860 }

Referenced by MVD_GameClientCommand().

◆ MVD_AutoFollow_f()

static void MVD_AutoFollow_f ( mvd_client_t client)
static

Definition at line 1132 of file game.c.

1133 {
1134  mvd_t *mvd = client->mvd;
1135  mvd_player_t *player;
1136  char *s, *p;
1137  int i, j, argc;
1138 
1139  if (!mvd->players) {
1140  SV_ClientPrintf(client->cl, PRINT_HIGH,
1141  "[MVD] Please enter a channel first.\n");
1142  return;
1143  }
1144 
1145  if (mvd->intermission)
1146  return;
1147 
1148  argc = Cmd_Argc();
1149  if (argc < 2) {
1150  i = count_chase_bits(client);
1151  SV_ClientPrintf(client->cl, PRINT_HIGH,
1152  "[MVD] Auto chasing is %s (%d target%s).\n",
1153  client->chase_auto ? "ON" : "OFF", i, i == 1 ? "" : "s");
1154  return;
1155  }
1156 
1157  s = Cmd_Argv(1);
1158  if (!strcmp(s, "add") || !strcmp(s, "rm") || !strcmp(s, "del")) {
1159  if (argc < 3) {
1160  SV_ClientPrintf(client->cl, PRINT_HIGH,
1161  "Usage: %s %s <wildcard> [...]\n",
1162  Cmd_Argv(0), Cmd_Argv(1));
1163  return;
1164  }
1165 
1166  for (i = 2; i < argc; i++) {
1167  p = Cmd_Argv(i);
1168  for (j = 0; j < mvd->maxclients; j++) {
1169  player = &mvd->players[j];
1170  if (!player->name[0] || player == mvd->dummy)
1171  continue;
1172 
1173  if (!Com_WildCmpEx(p, player->name, 0, qtrue))
1174  continue;
1175 
1176  if (*s == 'a')
1177  Q_SetBit(client->chase_bitmap, j);
1178  else
1179  Q_ClearBit(client->chase_bitmap, j);
1180  }
1181  }
1182 
1183  if (*s == 'a') {
1184  MVD_UpdateTarget(client);
1185  return;
1186  }
1187 
1188  if (!count_chase_bits(client))
1189  client->chase_auto = qfalse;
1190  return;
1191  }
1192 
1193  if (!strcmp(s, "set")) {
1194  memset(client->chase_bitmap, 0, sizeof(client->chase_bitmap));
1195 
1196  for (i = 2; i < argc; i++) {
1197  j = atoi(Cmd_Argv(i));
1198  if (j >= 0 && j < mvd->maxclients)
1199  Q_SetBit(client->chase_bitmap, j);
1200  }
1201 
1202  if (!count_chase_bits(client))
1203  client->chase_auto = qfalse;
1204  return;
1205  }
1206 
1207  if (!strcmp(s, "list")) {
1208  char buffer[1000];
1209  size_t total, len;
1210 
1211  total = 0;
1212  for (i = 0; i < mvd->maxclients; i++) {
1213  if (!Q_IsBitSet(client->chase_bitmap, i))
1214  continue;
1215 
1216  player = &mvd->players[i];
1217  if (player == mvd->dummy)
1218  continue;
1219 
1220  len = strlen(player->name);
1221  if (len == 0)
1222  continue;
1223 
1224  if (total + len + 2 >= sizeof(buffer))
1225  break;
1226 
1227  if (total) {
1228  buffer[total + 0] = ',';
1229  buffer[total + 1] = ' ';
1230  total += 2;
1231  }
1232 
1233  memcpy(buffer + total, player->name, len);
1234  total += len;
1235  }
1236  buffer[total] = 0;
1237 
1238  if (total)
1239  SV_ClientPrintf(client->cl, PRINT_HIGH,
1240  "[MVD] Auto chasing %s\n", buffer);
1241  else
1242  SV_ClientPrintf(client->cl, PRINT_HIGH,
1243  "[MVD] Auto chase list is empty.\n");
1244  return;
1245  }
1246 
1247  if (!strcmp(s, "on")) {
1248  if (!count_chase_bits(client)) {
1249  SV_ClientPrintf(client->cl, PRINT_HIGH,
1250  "[MVD] Please add auto chase targets first.\n");
1251  return;
1252  }
1253 
1254  client->chase_mask = 0;
1255  client->chase_auto = qtrue;
1256  client->chase_wait = qfalse;
1257  if (!MVD_TestTarget(client, client->target))
1258  MVD_FollowNext(client, client->target);
1259  return;
1260  }
1261 
1262  if (!strcmp(s, "off")) {
1263  client->chase_auto = qfalse;
1264  return;
1265  }
1266 
1267  SV_ClientPrintf(client->cl, PRINT_HIGH,
1268  "[MVD] Usage: %s <add|rm|set|list|on|off> [...]\n",
1269  Cmd_Argv(0));
1270 }

Referenced by MVD_GameClientCommand().

◆ MVD_BroadcastPrintf()

void MVD_BroadcastPrintf ( mvd_t mvd,
int  level,
int  mask,
const char *  fmt,
  ... 
)

Definition at line 707 of file game.c.

708 {
709  va_list argptr;
710  char text[MAX_STRING_CHARS];
711  size_t len;
713  client_t *cl;
714 
715  va_start(argptr, fmt);
716  len = Q_vsnprintf(text, sizeof(text), fmt, argptr);
717  va_end(argptr);
718 
719  if (len >= sizeof(text)) {
720  Com_WPrintf("%s: overflow\n", __func__);
721  return;
722  }
723 
724  if (level == PRINT_CHAT && mvd_filter_version->integer) {
725  char *s;
726 
727  while ((s = strstr(text, "!version")) != NULL) {
728  s[6] = '0';
729  }
730  }
731 
732  MSG_WriteByte(svc_print);
734  MSG_WriteData(text, len + 1);
735 
737  cl = other->cl;
738  if (cl->state < cs_spawned) {
739  continue;
740  }
741  if (level < cl->messagelevel) {
742  continue;
743  }
744  if (other->uf & mask) {
745  continue;
746  }
748  }
749 
751 }

Referenced by MVD_GameClientBegin(), MVD_GameClientDisconnect(), MVD_GameClientDrop(), MVD_GameClientNameChanged(), and MVD_TrySwitchChannel().

◆ mvd_channel_list_f()

static void mvd_channel_list_f ( mvd_client_t client)
static

Definition at line 1388 of file game.c.

1389 {
1390  mvd_t *mvd;
1391 
1392  SV_ClientPrintf(client->cl, PRINT_HIGH,
1393  "id name map spc plr who is playing\n"
1394  "-- ------------ -------- --- --- --------------\n");
1395 
1396  FOR_EACH_MVD(mvd) {
1397  print_channel(client->cl, mvd);
1398  }
1399 }

Referenced by MVD_GameClientCommand().

◆ MVD_Clients_f()

static void MVD_Clients_f ( mvd_client_t client)
static

Definition at line 1401 of file game.c.

1402 {
1403  // TODO: dump them in console
1404  client->layout_type = LAYOUT_CLIENTS;
1405  client->layout_time = 0;
1406  client->layout_cursor = 0;
1407 }

Referenced by MVD_GameClientCommand().

◆ MVD_Commands_f()

static void MVD_Commands_f ( mvd_client_t client)
static

Definition at line 1409 of file game.c.

1410 {
1411  SV_ClientPrintf(client->cl, PRINT_HIGH,
1412  "chase [player_id] toggle chasecam mode\n"
1413  "autochase <...> control automatic chasecam\n"
1414  "observe toggle observer mode\n"
1415  "menu show main menu\n"
1416  "score show scoreboard\n"
1417  "oldscore show previous scoreboard\n"
1418  "channels list active channels\n"
1419  "join [channel_id] join specified channel\n"
1420  "leave go to the Waiting Room\n"
1421  );
1422 }

Referenced by MVD_GameClientCommand().

◆ MVD_CountClients()

static int MVD_CountClients ( mvd_t mvd)
static

Definition at line 135 of file game.c.

136 {
137  mvd_client_t *c;
138  int count = 0;
139 
140  FOR_EACH_MVDCL(c, mvd) {
141  if (c->cl->state == cs_spawned) {
142  count++;
143  }
144  }
145  return count;
146 }

Referenced by MVD_LayoutChannels(), and MVD_LayoutMenu().

◆ MVD_Follow_f()

static void MVD_Follow_f ( mvd_client_t client)
static

Definition at line 1042 of file game.c.

1043 {
1044  mvd_t *mvd = client->mvd;
1045  mvd_player_t *player;
1046  char *s;
1047  int mask;
1048 
1049  if (!mvd->players) {
1050  SV_ClientPrintf(client->cl, PRINT_HIGH,
1051  "[MVD] Please enter a channel first.\n");
1052  return;
1053  }
1054 
1055  if (mvd->intermission) {
1056  return;
1057  }
1058 
1059  if (Cmd_Argc() < 2) {
1060  MVD_Observe_f(client);
1061  return;
1062  }
1063 
1064  s = Cmd_Argv(1);
1065  if (*s == '!') {
1066  s++;
1067  switch (*s) {
1068  case 'q':
1069  mask = EF_QUAD;
1070  break;
1071  case 'i':
1072  mask = EF_PENT;
1073  break;
1074  case 'r':
1075  mask = EF_FLAG1;
1076  break;
1077  case 'b':
1078  mask = EF_FLAG2;
1079  break;
1080  case '!':
1081  goto match;
1082  case 'p':
1083  if (client->oldtarget) {
1084  if (client->oldtarget->inuse) {
1085  MVD_FollowStart(client, client->oldtarget);
1086  } else {
1087  SV_ClientPrintf(client->cl, PRINT_HIGH,
1088  "[MVD] Previous chase target is not active.\n");
1089  }
1090  } else {
1091  SV_ClientPrintf(client->cl, PRINT_HIGH,
1092  "[MVD] You have no previous chase target.\n");
1093  }
1094  return;
1095  default:
1096  SV_ClientPrintf(client->cl, PRINT_HIGH,
1097  "[MVD] Unknown chase target '%s'. Valid targets are: "
1098  "q[uad]/i[nvulner]/r[ed_flag]/b[lue_flag]/p[revious_target].\n", s);
1099  return;
1100  }
1101  SV_ClientPrintf(client->cl, PRINT_MEDIUM,
1102  "[MVD] Chasing players with '%s' powerup.\n", s);
1103  client->chase_mask = mask;
1104  client->chase_auto = qfalse;
1105  client->chase_wait = qfalse;
1106  return;
1107  }
1108 
1109 match:
1110  player = MVD_SetPlayer(client, s);
1111  if (player) {
1112  MVD_FollowStart(client, player);
1113  client->chase_mask = 0;
1114  client->chase_wait = qfalse;
1115  }
1116 }

Referenced by MVD_GameClientCommand().

◆ MVD_FollowNext()

static mvd_player_t* MVD_FollowNext ( mvd_client_t client,
mvd_player_t from 
)
static

Definition at line 517 of file game.c.

518 {
519  mvd_t *mvd = client->mvd;
520  mvd_player_t *target;
521 
522  if (!mvd->players) {
523  return NULL;
524  }
525 
526  if (!from) {
527  from = mvd->players + mvd->maxclients - 1;
528  }
529 
530  target = from;
531  do {
532  if (target == mvd->players + mvd->maxclients - 1) {
533  target = mvd->players;
534  } else {
535  target++;
536  }
537  if (target == from) {
538  return NULL;
539  }
540  } while (!MVD_TestTarget(client, target));
541 
542  MVD_FollowStart(client, target);
543  return target;
544 }

Referenced by MVD_AutoFollow_f(), MVD_GameClientCommand(), MVD_GameClientThink(), MVD_Observe_f(), and MVD_UpdateTarget().

◆ MVD_FollowPrev()

static mvd_player_t* MVD_FollowPrev ( mvd_client_t client,
mvd_player_t from 
)
static

Definition at line 546 of file game.c.

547 {
548  mvd_t *mvd = client->mvd;
549  mvd_player_t *target;
550 
551  if (!mvd->players) {
552  return NULL;
553  }
554 
555  if (!from) {
556  from = mvd->players;
557  }
558 
559  target = from;
560  do {
561  if (target == mvd->players) {
562  target = mvd->players + mvd->maxclients - 1;
563  } else {
564  target--;
565  }
566  if (target == from) {
567  return NULL;
568  }
569  } while (!MVD_TestTarget(client, target));
570 
571  MVD_FollowStart(client, target);
572  return target;
573 }

Referenced by MVD_GameClientCommand(), and MVD_GameClientThink().

◆ MVD_FollowStart()

static void MVD_FollowStart ( mvd_client_t client,
mvd_player_t target 
)
static

Definition at line 480 of file game.c.

481 {
482  if (client->target == target) {
483  return;
484  }
485 
486  client->oldtarget = client->target;
487  client->target = target;
488 
489  // send delta configstrings
490  write_cs_list(client, target->configstrings);
491 
492  SV_ClientPrintf(client->cl, PRINT_LOW, "[MVD] Chasing %s.\n", target->name);
493 
494  MVD_SetFollowLayout(client);
495  MVD_UpdateClient(client);
496 }

Referenced by MVD_Follow_f(), MVD_FollowNext(), MVD_FollowPrev(), MVD_GameClientBegin(), MVD_IntermissionStop(), MVD_Observe_f(), and MVD_UpdateTarget().

◆ MVD_FollowStop()

static void MVD_FollowStop ( mvd_client_t client)
static

Definition at line 445 of file game.c.

446 {
447  mvd_t *mvd = client->mvd;
448  int i;
449 
450  client->ps.viewangles[ROLL] = 0;
451 
452  for (i = 0; i < 3; i++) {
453  client->ps.pmove.delta_angles[i] = ANGLE2SHORT(
454  client->ps.viewangles[i]) - client->lastcmd.angles[i];
455  }
456 
457  VectorClear(client->ps.kick_angles);
458  Vector4Clear(client->ps.blend);
459  client->ps.pmove.pm_flags = 0;
460  client->ps.pmove.pm_type = mvd->pm_type;
461  client->ps.rdflags = 0;
462  client->ps.gunindex = 0;
463  client->ps.fov = client->fov;
464 
465  // send delta configstrings
466  if (mvd->dummy)
468 
469  client->clientNum = mvd->clientNum;
470  client->oldtarget = client->target;
471  client->target = NULL;
472 
473  if (client->layout_type == LAYOUT_FOLLOW) {
474  MVD_SetDefaultLayout(client);
475  }
476 
477  MVD_UpdateClient(client);
478 }

Referenced by MVD_GameClientBegin(), MVD_IntermissionStop(), MVD_Observe_f(), and MVD_UpdateTarget().

◆ MVD_Forward_f()

static void MVD_Forward_f ( mvd_client_t client)
static

Definition at line 862 of file game.c.

863 {
864  mvd_t *mvd = client->mvd;
865 
866  if (!client->admin) {
867  SV_ClientPrintf(client->cl, PRINT_HIGH,
868  "[MVD] You don't have admin status.\n");
869  return;
870  }
871 
872  if (!mvd->forward_cmd) {
873  SV_ClientPrintf(client->cl, PRINT_HIGH,
874  "[MVD] This channel does not support command forwarding.\n");
875  return;
876  }
877 
878  mvd->forward_cmd(client);
879 }

Referenced by MVD_GameClientCommand().

◆ MVD_FreePlayer()

void MVD_FreePlayer ( mvd_player_t player)

Definition at line 1540 of file game.c.

1541 {
1542  mvd_cs_t *cs, *next;
1543 
1544  for (cs = player->configstrings; cs; cs = next) {
1545  next = cs->next;
1546  Z_Free(cs);
1547  }
1548  player->configstrings = NULL;
1549 }

Referenced by MVD_ClearState(), and MVD_Free().

◆ MVD_GameClientBegin()

static void MVD_GameClientBegin ( edict_t *  ent)
static

Definition at line 1840 of file game.c.

1841 {
1842  mvd_client_t *client = EDICT_MVDCL(ent);
1843  mvd_t *mvd = client->mvd;
1844  mvd_player_t *target;
1845 
1846  client->floodTime = 0;
1847  client->floodHead = 0;
1848  memset(&client->lastcmd, 0, sizeof(client->lastcmd));
1849  memset(&client->ps, 0, sizeof(client->ps));
1850  client->jump_held = 0;
1851  client->layout_type = LAYOUT_NONE;
1852  client->layout_time = 0;
1853  client->layout_cursor = 0;
1854  client->notified = qfalse;
1855 
1856  // skip notifications for local clients
1857  if (NET_IsLocalAddress(&client->cl->netchan->remote_address))
1858  client->notified = qtrue;
1859 
1860  // skip notifications for Waiting Room channel
1861  if (mvd == &mvd_waitingRoom)
1862  client->notified = qtrue;
1863 
1864  if (!client->begin_time) {
1865  if (MVD_PartFilter(client)) {
1866  MVD_BroadcastPrintf(mvd, PRINT_MEDIUM, UF_MUTE_MISC,
1867  "[MVD] %s entered the channel\n", client->cl->name);
1868  }
1869  target = MVD_MostFollowed(mvd);
1870  } else if (mvd->flags & MVF_SINGLEPOV) {
1871  target = MVD_MostFollowed(mvd);
1872  } else {
1873  target = client->oldtarget;
1874  }
1875 
1876  client->target = NULL;
1877  client->begin_time = svs.realtime;
1878 
1879  MVD_SetDefaultLayout(client);
1880 
1881  if (mvd->intermission) {
1882  // force them to chase dummy MVD client
1883  client->target = mvd->dummy;
1884  MVD_SetFollowLayout(client);
1885  MVD_UpdateClient(client);
1886  } else if (target && target->inuse) {
1887  // start normal chase cam mode
1888  MVD_FollowStart(client, target);
1889  } else {
1890  // spawn the spectator
1891  VectorScale(mvd->spawnOrigin, 8, client->ps.pmove.origin);
1892  VectorCopy(mvd->spawnAngles, client->ps.viewangles);
1893  MVD_FollowStop(client);
1894 
1895  // if the map has just changed, player might not have spawned yet.
1896  // save the old target and try to return to it later.
1897  client->oldtarget = target;
1898  client->chase_wait = qtrue;
1899  }
1900 
1901  mvd_dirty = qtrue;
1902 }

◆ MVD_GameClientCommand()

static void MVD_GameClientCommand ( edict_t *  ent)
static

Definition at line 1424 of file game.c.

1425 {
1426  mvd_client_t *client = EDICT_MVDCL(ent);
1427  char *cmd;
1428 
1429  if (client->cl->state < cs_spawned) {
1430  return;
1431  }
1432 
1433  cmd = Cmd_Argv(0);
1434  if (!*cmd) {
1435  return;
1436  }
1437 
1438  // don't timeout
1440 
1441  if (!strcmp(cmd, "!mvdadmin")) {
1442  MVD_Admin_f(client);
1443  return;
1444  }
1445  if (!strcmp(cmd, "fwd")) {
1446  MVD_Forward_f(client);
1447  return;
1448  }
1449  if (!strcmp(cmd, "say") || !strcmp(cmd, "say_team")) {
1450  MVD_Say_f(client, 1);
1451  return;
1452  }
1453  if (!strcmp(cmd, "follow") || !strcmp(cmd, "chase")) {
1454  MVD_Follow_f(client);
1455  return;
1456  }
1457  if (!strcmp(cmd, "autofollow") || !strcmp(cmd, "autochase")) {
1458  MVD_AutoFollow_f(client);
1459  return;
1460  }
1461  if (!strcmp(cmd, "observe") || !strcmp(cmd, "spectate") ||
1462  !strcmp(cmd, "observer") || !strcmp(cmd, "spectator") ||
1463  !strcmp(cmd, "obs") || !strcmp(cmd, "spec")) {
1464  MVD_Observe_f(client);
1465  return;
1466  }
1467  if (!strcmp(cmd, "inven") || !strcmp(cmd, "menu")) {
1468  MVD_ToggleLayout(client, LAYOUT_MENU);
1469  return;
1470  }
1471  if (!strcmp(cmd, "invnext")) {
1472  if (client->layout_type >= LAYOUT_MENU) {
1473  client->layout_cursor++;
1474  client->layout_time = 0;
1475  } else if (!client->mvd->intermission) {
1476  MVD_FollowNext(client, client->target);
1477  client->chase_mask = 0;
1478  }
1479  return;
1480  }
1481  if (!strcmp(cmd, "invprev")) {
1482  if (client->layout_type >= LAYOUT_MENU) {
1483  client->layout_cursor--;
1484  client->layout_time = 0;
1485  } else if (!client->mvd->intermission) {
1486  MVD_FollowPrev(client, client->target);
1487  client->chase_mask = 0;
1488  }
1489  return;
1490  }
1491  if (!strcmp(cmd, "invuse")) {
1492  MVD_Invuse_f(client);
1493  return;
1494  }
1495  if (!strcmp(cmd, "help") || !strcmp(cmd, "score")) {
1497  return;
1498  }
1499  if (!strcmp(cmd, "oldscore") || !strcmp(cmd, "oldscores") ||
1500  !strcmp(cmd, "lastscore") || !strcmp(cmd, "lastscores")) {
1502  return;
1503  }
1504  if (!strcmp(cmd, "putaway")) {
1505  MVD_SetDefaultLayout(client);
1506  return;
1507  }
1508  if (!strcmp(cmd, "channels")) {
1509  mvd_channel_list_f(client);
1510  return;
1511  }
1512  if (!strcmp(cmd, "clients") || !strcmp(cmd, "players")) {
1513  MVD_Clients_f(client);
1514  return;
1515  }
1516  if (!strcmp(cmd, "join")) {
1517  MVD_Join_f(client);
1518  return;
1519  }
1520  if (!strcmp(cmd, "leave")) {
1522  return;
1523  }
1524  if (!strcmp(cmd, "commands")) {
1525  MVD_Commands_f(client);
1526  return;
1527  }
1528 
1529  MVD_Say_f(client, 0);
1530 }

◆ MVD_GameClientConnect()

static qboolean MVD_GameClientConnect ( edict_t *  ent,
char *  userinfo 
)
static

Definition at line 1816 of file game.c.

1817 {
1818  mvd_client_t *client = EDICT_MVDCL(ent);
1819  mvd_t *mvd;
1820 
1821  // if there is exactly one active channel, assign them to it,
1822  // otherwise, assign to Waiting Room
1823  if (LIST_SINGLE(&mvd_channel_list)) {
1824  mvd = LIST_FIRST(mvd_t, &mvd_channel_list, entry);
1825  } else {
1826  mvd = &mvd_waitingRoom;
1827  }
1828  List_SeqAdd(&mvd->clients, &client->entry);
1829  client->mvd = mvd;
1830 
1831  // override server state
1832  MVD_SetServerState(client->cl, mvd);
1833 
1834  // don't timeout
1836 
1837  return qtrue;
1838 }

◆ MVD_GameClientDisconnect()

static void MVD_GameClientDisconnect ( edict_t *  ent)
static

Definition at line 1947 of file game.c.

1948 {
1949  mvd_client_t *client = EDICT_MVDCL(ent);
1950  client_t *cl = client->cl;
1951 
1952  if (client->begin_time && MVD_PartFilter(client)) {
1953  MVD_BroadcastPrintf(client->mvd, PRINT_MEDIUM, UF_MUTE_MISC,
1954  "[MVD] %s disconnected\n", cl->name);
1955  }
1956 
1957  client->begin_time = 0;
1958 }

◆ MVD_GameClientDrop()

void MVD_GameClientDrop ( edict_t *  ent,
const char *  prefix,
const char *  reason 
)

Definition at line 1934 of file game.c.

1935 {
1936  mvd_client_t *client = EDICT_MVDCL(ent);
1937  client_t *cl = client->cl;
1938 
1939  if (client->begin_time && MVD_PartFilter(client)) {
1940  MVD_BroadcastPrintf(client->mvd, PRINT_MEDIUM, UF_MUTE_MISC,
1941  "[MVD] %s%s%s\n", cl->name, prefix, reason);
1942  }
1943 
1944  client->begin_time = 0;
1945 }

Referenced by print_drop_reason().

◆ MVD_GameClientNameChanged()

void MVD_GameClientNameChanged ( edict_t *  ent,
const char *  name 
)

Definition at line 1922 of file game.c.

1923 {
1924  mvd_client_t *client = EDICT_MVDCL(ent);
1925  client_t *cl = client->cl;
1926 
1927  if (client->begin_time && MVD_PartFilter(client)) {
1928  MVD_BroadcastPrintf(client->mvd, PRINT_MEDIUM, UF_MUTE_MISC,
1929  "[MVD] %s changed name to %s\n", cl->name, name);
1930  }
1931 }

Referenced by SV_UserinfoChanged().

◆ MVD_GameClientThink()

static void MVD_GameClientThink ( edict_t *  ent,
usercmd_t *  cmd 
)
static

Definition at line 2030 of file game.c.

2031 {
2032  mvd_client_t *client = EDICT_MVDCL(ent);
2033  usercmd_t *old = &client->lastcmd;
2034  pmove_t pm;
2035 
2036  if (cmd->buttons != old->buttons
2037  || cmd->forwardmove != old->forwardmove
2038  || cmd->sidemove != old->sidemove
2039  || cmd->upmove != old->upmove) {
2040  // don't timeout
2042  }
2043 
2044  if ((cmd->buttons & ~old->buttons) & BUTTON_ATTACK) {
2045  mvd_player_t *hit;
2046 
2047  // small hack to allow picking up targets by aim
2048  if (client->target == NULL && (hit = MVD_HitPlayer(client)) != NULL) {
2049  client->oldtarget = hit;
2050  }
2051 
2052  MVD_Observe_f(client);
2053  }
2054 
2055  if (client->target) {
2056  if (cmd->upmove >= 10) {
2057  if (client->jump_held < 1) {
2058  if (!client->mvd->intermission) {
2059  MVD_FollowNext(client, client->target);
2060  client->chase_mask = 0;
2061  }
2062  client->jump_held = 1;
2063  }
2064  } else if (cmd->upmove <= -10) {
2065  if (client->jump_held > -1) {
2066  if (!client->mvd->intermission) {
2067  MVD_FollowPrev(client, client->target);
2068  client->chase_mask = 0;
2069  }
2070  client->jump_held = -1;
2071  }
2072  } else {
2073  client->jump_held = 0;
2074  }
2075  } else {
2076  memset(&pm, 0, sizeof(pm));
2077  pm.trace = MVD_Trace;
2078  pm.pointcontents = MVD_PointContents;
2079  pm.s = client->ps.pmove;
2080  pm.cmd = *cmd;
2081 
2082  PF_Pmove(&pm);
2083 
2084  client->ps.pmove = pm.s;
2085  if (pm.s.pm_type != PM_FREEZE) {
2086  VectorCopy(pm.viewangles, client->ps.viewangles);
2087  }
2088  }
2089 
2090  *old = *cmd;
2091 }

◆ MVD_GameClientUserinfoChanged()

static void MVD_GameClientUserinfoChanged ( edict_t *  ent,
char *  userinfo 
)
static

Definition at line 1904 of file game.c.

1905 {
1906  mvd_client_t *client = EDICT_MVDCL(ent);
1907  float fov;
1908 
1909  client->uf = atoi(Info_ValueForKey(userinfo, "uf"));
1910 
1911  fov = atof(Info_ValueForKey(userinfo, "fov"));
1912  if (fov < 1) {
1913  fov = 90;
1914  } else if (fov > 160) {
1915  fov = 160;
1916  }
1917  client->fov = fov;
1918  if (!client->target)
1919  client->ps.fov = fov;
1920 }

◆ MVD_GameInit()

static void MVD_GameInit ( void  )
static

Definition at line 1696 of file game.c.

1697 {
1699  edict_t *edicts;
1700  cvar_t *mvd_default_map;
1701  char buffer[MAX_QPATH];
1702  unsigned checksum;
1703  bsp_t *bsp;
1704  int i;
1705  qerror_t ret;
1706 
1707  Com_Printf("----- MVD_GameInit -----\n");
1708 
1709  mvd_admin_password = Cvar_Get("mvd_admin_password", "", CVAR_PRIVATE);
1710  mvd_part_filter = Cvar_Get("mvd_part_filter", "0", 0);
1711  mvd_flood_msgs = Cvar_Get("flood_msgs", "4", 0);
1712  mvd_flood_persecond = Cvar_Get("flood_persecond", "4", 0); // FIXME: rename this
1713  mvd_flood_waitdelay = Cvar_Get("flood_waitdelay", "10", 0);
1714  mvd_flood_mute = Cvar_Get("flood_mute", "0", 0);
1715  mvd_filter_version = Cvar_Get("mvd_filter_version", "0", 0);
1716  mvd_default_map = Cvar_Get("mvd_default_map", "q2dm1", CVAR_LATCH);
1717  mvd_stats_score = Cvar_Get("mvd_stats_score", "0", 0);
1718  mvd_stats_hack = Cvar_Get("mvd_stats_hack", "0", 0);
1719  mvd_freeze_hack = Cvar_Get("mvd_freeze_hack", "1", 0);
1720  mvd_chase_prefix = Cvar_Get("mvd_chase_prefix", "xv 0 yb -64", 0);
1721  Cvar_Set("g_features", va("%d", MVD_FEATURES));
1722 
1723  Z_TagReserve((sizeof(edict_t) +
1724  sizeof(mvd_client_t)) * sv_maxclients->integer +
1725  sizeof(edict_t), TAG_MVD);
1727  sv_maxclients->integer);
1728  edicts = Z_ReservedAllocz(sizeof(edict_t) *
1729  (sv_maxclients->integer + 1));
1730 
1731  for (i = 0; i < sv_maxclients->integer; i++) {
1732  mvd_clients[i].cl = &svs.client_pool[i];
1733  edicts[i + 1].client = (gclient_t *)&mvd_clients[i];
1734  }
1735 
1736  mvd_ge.edicts = edicts;
1737  mvd_ge.edict_size = sizeof(edict_t);
1738  mvd_ge.num_edicts = sv_maxclients->integer + 1;
1739  mvd_ge.max_edicts = sv_maxclients->integer + 1;
1740 
1741  Q_snprintf(buffer, sizeof(buffer),
1742  "maps/%s.bsp", mvd_default_map->string);
1743 
1744  ret = BSP_Load(buffer, &bsp);
1745  if (!bsp) {
1746  Com_EPrintf("Couldn't load %s for the Waiting Room: %s\n",
1747  buffer, Q_ErrorString(ret));
1748  Cvar_Reset(mvd_default_map);
1749  strcpy(buffer, "maps/q2dm1.bsp");
1750  checksum = 80717714;
1751  VectorSet(mvd->spawnOrigin, 984, 192, 784);
1752  VectorSet(mvd->spawnAngles, 25, 72, 0);
1753  } else {
1754  // get the spectator spawn point
1755  MVD_ParseEntityString(mvd, bsp->entitystring);
1756  checksum = bsp->checksum;
1757  BSP_Free(bsp);
1758  }
1759 
1760  strcpy(mvd->name, "Waiting Room");
1761  Cvar_VariableStringBuffer("game", mvd->gamedir, sizeof(mvd->gamedir));
1762  Q_strlcpy(mvd->mapname, mvd_default_map->string, sizeof(mvd->mapname));
1763  List_Init(&mvd->clients);
1764 
1765  strcpy(mvd->configstrings[CS_NAME], "Waiting Room");
1766  strcpy(mvd->configstrings[CS_SKY], "unit1_");
1767  strcpy(mvd->configstrings[CS_MAXCLIENTS], "8");
1768  sprintf(mvd->configstrings[CS_MAPCHECKSUM], "%d", checksum);
1769  strcpy(mvd->configstrings[CS_MODELS + 1], buffer);
1770  strcpy(mvd->configstrings[CS_LIGHTS], "m");
1771 
1772  mvd->dummy = &mvd_dummy;
1773  mvd->pm_type = PM_FREEZE;
1774  mvd->servercount = sv.spawncount;
1775 
1776  // set serverinfo variables
1777  SV_InfoSet("mapname", mvd->mapname);
1778  //SV_InfoSet("gamedir", "gtv");
1779  SV_InfoSet("gamename", "gtv");
1780  SV_InfoSet("gamedate", __DATE__);
1781  MVD_InfoSet("mvd_channels", "0");
1782  MVD_InfoSet("mvd_players", "0");
1783  mvd_numplayers = 0;
1784 }

◆ MVD_GameReadGame()

static void MVD_GameReadGame ( const char *  filename)
static

Definition at line 1806 of file game.c.

1807 {
1808 }

◆ MVD_GameReadLevel()

static void MVD_GameReadLevel ( const char *  filename)
static

Definition at line 1812 of file game.c.

1813 {
1814 }

◆ MVD_GameRunFrame()

static void MVD_GameRunFrame ( void  )
static

Definition at line 2220 of file game.c.

2221 {
2222  mvd_t *mvd, *next;
2223  int numplayers = 0;
2224 
2225  LIST_FOR_EACH_SAFE(mvd_t, mvd, next, &mvd_channel_list, entry) {
2226  if (setjmp(mvd_jmpbuf)) {
2227  continue;
2228  }
2229 
2230  // parse stream
2231  if (!mvd->read_frame(mvd)) {
2232  goto update;
2233  }
2234 
2235  // write this message to demofile
2236  if (mvd->demorecording) {
2238  }
2239 
2240 update:
2242  numplayers += mvd->numplayers;
2243  }
2244 
2246 
2247  if (mvd_dirty) {
2248  MVD_InfoSet("mvd_channels", va("%d", List_Count(&mvd_channel_list)));
2249  mvd_dirty = qfalse;
2250  }
2251 
2252  if (numplayers != mvd_numplayers) {
2253  MVD_InfoSet("mvd_players", va("%d", numplayers));
2254  mvd_numplayers = numplayers;
2255  mvd_dirty = qtrue; // update layouts next frame
2256  }
2257 }

◆ MVD_GameServerCommand()

static void MVD_GameServerCommand ( void  )
static

Definition at line 2259 of file game.c.

2260 {
2261 }

◆ MVD_GameShutdown()

static void MVD_GameShutdown ( void  )
static

Definition at line 1786 of file game.c.

1787 {
1788  Com_Printf("----- MVD_GameShutdown -----\n");
1789 
1790  MVD_Shutdown();
1791 
1792  mvd_ge.edicts = NULL;
1793  mvd_ge.edict_size = 0;
1794  mvd_ge.num_edicts = 0;
1795  mvd_ge.max_edicts = 0;
1796 
1797  Cvar_Set("g_features", "0");
1798 }

◆ MVD_GameSpawnEntities()

static void MVD_GameSpawnEntities ( const char *  mapname,
const char *  entstring,
const char *  spawnpoint 
)
static

Definition at line 1800 of file game.c.

1801 {
1802 }

◆ MVD_GameWriteGame()

static void MVD_GameWriteGame ( const char *  filename,
qboolean  autosave 
)
static

Definition at line 1803 of file game.c.

1804 {
1805 }

◆ MVD_GameWriteLevel()

static void MVD_GameWriteLevel ( const char *  filename)
static

Definition at line 1809 of file game.c.

1810 {
1811 }

◆ MVD_HitPlayer()

static mvd_player_t* MVD_HitPlayer ( mvd_client_t client)
static

Definition at line 1960 of file game.c.

1961 {
1962  mvd_t *mvd = client->mvd;
1963  trace_t trace;
1964  vec3_t start, end, forward;
1965  mvd_player_t *player, *target;
1966  edict_t *ent;
1967  float fraction;
1968  int i;
1969 
1970  if (!mvd->players)
1971  return NULL;
1972 
1973  if (mvd->intermission)
1974  return NULL;
1975 
1976  VectorMA(client->ps.viewoffset, 0.125f, client->ps.pmove.origin, start);
1977  AngleVectors(client->ps.viewangles, forward, NULL, NULL);
1978  VectorMA(start, 8192, forward, end);
1979 
1980  if (mvd->cm.cache) {
1981  CM_BoxTrace(&trace, start, end, vec3_origin, vec3_origin,
1982  mvd->cm.cache->nodes, CONTENTS_SOLID);
1983  fraction = trace.fraction;
1984  } else {
1985  fraction = 1;
1986  }
1987 
1988  target = NULL;
1989  for (i = 0; i < mvd->maxclients; i++) {
1990  player = &mvd->players[i];
1991  if (!player->inuse || player == mvd->dummy)
1992  continue;
1993 
1994  ent = &mvd->edicts[i + 1];
1995  if (!ent->inuse)
1996  continue;
1997 
1998  if (ent->solid != SOLID_BBOX)
1999  continue;
2000 
2001  CM_TransformedBoxTrace(&trace, start, end, vec3_origin, vec3_origin,
2002  CM_HeadnodeForBox(ent->mins, ent->maxs),
2003  CONTENTS_MONSTER, ent->s.origin, vec3_origin);
2004 
2005  if (trace.fraction < fraction) {
2006  fraction = trace.fraction;
2007  target = player;
2008  }
2009  }
2010 
2011  return target;
2012 }

Referenced by MVD_GameClientThink().

◆ MVD_IntermissionStart()

static void MVD_IntermissionStart ( mvd_t mvd)
static

Definition at line 2093 of file game.c.

2094 {
2095  mvd_client_t *client;
2096 
2097  // set this early so MVD_SetDefaultLayout works
2098  mvd->intermission = qtrue;
2099 
2100 #if 0
2101  // save oldscores
2102  // FIXME: unfortunately this will also reset oldscores during
2103  // match timeout with certain mods (OpenTDM should work fine though)
2104  strcpy(mvd->oldscores, mvd->layout);
2105 #endif
2106 
2107  // force all clients to switch to the MVD dummy
2108  // and open the scoreboard, unless they had some special layout up
2109  FOR_EACH_MVDCL(client, mvd) {
2110  if (client->cl->state != cs_spawned) {
2111  continue;
2112  }
2113  client->oldtarget = client->target;
2114  client->target = mvd->dummy;
2115  if (client->layout_type < LAYOUT_SCORES) {
2116  MVD_SetDefaultLayout(client);
2117  }
2118  }
2119 }

Referenced by MVD_UpdateClients().

◆ MVD_IntermissionStop()

static void MVD_IntermissionStop ( mvd_t mvd)
static

Definition at line 2121 of file game.c.

2122 {
2123  mvd_client_t *client;
2124  mvd_player_t *target;
2125 
2126  // set this early so MVD_SetDefaultLayout works
2127  mvd->intermission = qfalse;
2128 
2129  // force all clients to switch to previous mode
2130  // and close the scoreboard
2131  FOR_EACH_MVDCL(client, mvd) {
2132  if (client->cl->state != cs_spawned) {
2133  continue;
2134  }
2135  if (client->layout_type == LAYOUT_SCORES) {
2136  client->layout_type = 0;
2137  }
2138  target = client->oldtarget;
2139  if (target && target->inuse) {
2140  // start normal chase cam mode
2141  MVD_FollowStart(client, target);
2142  } else {
2143  MVD_FollowStop(client);
2144  }
2145  client->oldtarget = NULL;
2146  }
2147 }

Referenced by MVD_UpdateClients().

◆ MVD_Invuse_f()

static void MVD_Invuse_f ( mvd_client_t client)
static

Definition at line 1272 of file game.c.

1273 {
1274  mvd_t *mvd;
1275  int uf = client->uf;
1276 
1277  if (client->layout_type == LAYOUT_MENU) {
1278  switch (clamp_menu_cursor(client)) {
1279  case 0:
1280  MVD_SetDefaultLayout(client);
1281  MVD_Observe_f(client);
1282  return;
1283  case 1:
1285  break;
1286  case 2:
1288  break;
1289  case 3:
1291  break;
1292  case 4:
1294  return;
1295  case 5:
1296  client->uf ^= UF_MUTE_OBSERVERS;
1297  break;
1298  case 6:
1299  client->uf ^= UF_MUTE_MISC;
1300  break;
1301  case 7:
1302  client->uf ^= UF_MUTE_PLAYERS;
1303  break;
1304  case 8:
1305  client->uf &= ~(UF_LOCALFOV | UF_PLAYERFOV);
1306  if (uf & UF_LOCALFOV)
1307  client->uf |= UF_PLAYERFOV;
1308  else if (!(uf & UF_PLAYERFOV))
1309  client->uf |= UF_LOCALFOV;
1310  break;
1311  case 9:
1312  MVD_SetDefaultLayout(client);
1313  break;
1314  }
1315  if (uf != client->uf) {
1316  SV_ClientCommand(client->cl, "set uf %d u\n", client->uf);
1317  client->layout_time = 0; // force an update
1318  }
1319  return;
1320  }
1321 
1322  if (client->layout_type == LAYOUT_CHANNELS) {
1323  mvd = LIST_INDEX(mvd_t, client->layout_cursor, &mvd_channel_list, entry);
1324  if (mvd) {
1325  MVD_TrySwitchChannel(client, mvd);
1326  }
1327  return;
1328  }
1329 }

Referenced by MVD_GameClientCommand().

◆ MVD_Join_f()

static void MVD_Join_f ( mvd_client_t client)
static

Definition at line 1331 of file game.c.

1332 {
1333  mvd_t *mvd;
1334 
1336  mvd = MVD_SetChannel(1);
1337  Com_EndRedirect();
1338 
1339  if (!mvd) {
1340  return;
1341  }
1342  if (mvd->state < MVD_WAITING) {
1343  SV_ClientPrintf(client->cl, PRINT_HIGH,
1344  "[MVD] This channel is not ready yet.\n");
1345  return;
1346  }
1347 
1348  MVD_TrySwitchChannel(client, mvd);
1349 }

Referenced by MVD_GameClientCommand().

◆ MVD_LayoutChannels()

static void MVD_LayoutChannels ( mvd_client_t client)
static

Definition at line 148 of file game.c.

149 {
150  static const char header[] =
151  "xv 32 yv 8 picn inventory "
152  "xv %d yv 172 string2 " VERSION_STRING " "
153  "xv 0 yv 32 cstring \"\020Channel Chooser\021\""
154  "xv 64 yv 48 string2 \"Name Map S/P\""
155  "yv 56 string \"------------ ------- ---\" xv 56 ";
156  static const char nochans[] =
157  "yv 72 string \" No active channels.\""
158  "yv 80 string \" Please wait until players\""
159  "yv 88 string \" connect.\""
160  ;
161  static const char inactive[] =
162  "yv 72 string \" Traffic saving mode.\""
163  "yv 80 string \" Press any key to wake\""
164  "yv 88 string \" this server up.\""
165  ;
166  char layout[MAX_STRING_CHARS];
167  char buffer[MAX_QPATH];
168  mvd_t *mvd;
169  size_t len, total;
170  int cursor, y;
171 
172  total = Q_scnprintf(layout, sizeof(layout),
173  header, VER_OFS);
174 
175  // FIXME: improve this
176  cursor = List_Count(&mvd_channel_list);
177  if (cursor) {
178  if (client->layout_cursor < 0) {
179  client->layout_cursor = cursor - 1;
180  } else if (client->layout_cursor > cursor - 1) {
181  client->layout_cursor = 0;
182  }
183 
184  y = 64;
185  cursor = 0;
186  FOR_EACH_MVD(mvd) {
187  len = Q_snprintf(buffer, sizeof(buffer),
188  "yv %d string%s \"%c%-12.12s %-7.7s %d/%d\" ", y,
189  mvd == client->mvd ? "2" : "",
190  cursor == client->layout_cursor ? 0x8d : 0x20,
191  mvd->name, mvd->mapname,
192  MVD_CountClients(mvd), mvd->numplayers);
193  if (len >= sizeof(buffer)) {
194  continue;
195  }
196  if (total + len >= sizeof(layout)) {
197  break;
198  }
199  memcpy(layout + total, buffer, len);
200  total += len;
201  y += 8;
202  if (y > 164) {
203  break;
204  }
205 
206  cursor++;
207  }
208  } else {
209  client->layout_cursor = 0;
210  if (mvd_active) {
211  memcpy(layout + total, nochans, sizeof(nochans) - 1);
212  total += sizeof(nochans) - 1;
213  } else {
214  memcpy(layout + total, inactive, sizeof(inactive) - 1);
215  total += sizeof(inactive) - 1;
216  }
217  }
218 
219  layout[total] = 0;
220 
221  // send the layout
223  MSG_WriteData(layout, total + 1);
225 
226  client->layout_time = svs.realtime;
227 }

Referenced by MVD_UpdateLayouts().

◆ MVD_LayoutClients()

static void MVD_LayoutClients ( mvd_client_t client)
static

Definition at line 58 of file game.c.

59 {
60  static const char header[] =
61  "xv 16 yv 0 string2 \" Name RTT Status\"";
62  char layout[MAX_STRING_CHARS];
63  char buffer[MAX_QPATH];
64  char *status1, *status2;
65  size_t len, total;
67  mvd_t *mvd = client->mvd;
68  int y, i, prestep, flags;
69 
70  // calculate prestep
71  if (client->layout_cursor < 0) {
72  client->layout_cursor = 0;
73  } else if (client->layout_cursor) {
74  total = List_Count(&mvd->clients);
75  if (client->layout_cursor > total / PAGE_CLIENTS) {
76  client->layout_cursor = total / PAGE_CLIENTS;
77  }
78  }
79 
80  prestep = client->layout_cursor * PAGE_CLIENTS;
81 
82  memcpy(layout, header, sizeof(header) - 1);
83  total = sizeof(header) - 1;
84 
85  y = 8;
86  i = 0;
88  if (++i < prestep) {
89  continue;
90  }
91  if (cl->cl->state < cs_spawned) {
92  continue;
93  }
94  if (cl->target && cl->target != mvd->dummy) {
95  status1 = "-> ";
96  status2 = cl->target->name;
97  } else {
98  status1 = "observing";
99  status2 = "";
100  }
101  len = Q_snprintf(buffer, sizeof(buffer),
102  "yv %d string \"%3d %-15.15s %3d %s%s\"",
103  y, i, cl->cl->name, cl->ping, status1, status2);
104  if (len >= sizeof(buffer)) {
105  continue;
106  }
107  if (total + len >= sizeof(layout)) {
108  break;
109  }
110  memcpy(layout + total, buffer, len);
111  total += len;
112 
113  if (y > 8 * PAGE_CLIENTS) {
114  break;
115  }
116  y += 8;
117  }
118 
119  layout[total] = 0;
120 
121  // the very first layout update is reliably delivered
122  flags = MSG_CLEAR | MSG_COMPRESS;
123  if (!client->layout_time) {
124  flags |= MSG_RELIABLE;
125  }
126 
127  // send the layout
129  MSG_WriteData(layout, total + 1);
130  SV_ClientAddMessage(client->cl, flags);
131 
132  client->layout_time = svs.realtime;
133 }

Referenced by MVD_UpdateLayouts().

◆ MVD_LayoutFollow()

static void MVD_LayoutFollow ( mvd_client_t client)
static

Definition at line 318 of file game.c.

319 {
320  mvd_t *mvd = client->mvd;
321  char *name = client->target ? client->target->name : "<no target>";
322  char layout[MAX_STRING_CHARS];
323  size_t total;
324 
325  total = Q_scnprintf(layout, sizeof(layout),
326  "%s string \"[%s] Chasing %s\"",
327  mvd_chase_prefix->string, mvd->name, name);
328 
329  // send the layout
331  MSG_WriteData(layout, total + 1);
333 
334  client->layout_time = svs.realtime;
335 }

Referenced by MVD_UpdateLayouts().

◆ MVD_LayoutMenu()

static void MVD_LayoutMenu ( mvd_client_t client)
static

Definition at line 244 of file game.c.

245 {
246  static const char format[] =
247  "xv 32 yv 8 picn inventory "
248  "xv 0 yv 32 cstring \"\020Main Menu\021\" xv 56 "
249  "yv 48 string2 \"%c%s in-eyes mode\""
250  "yv 56 string2 \"%cShow scoreboard\""
251  "yv 64 string2 \"%cShow spectators (%d)\""
252  "yv 72 string2 \"%cShow channels (%d)\""
253  "yv 80 string2 \"%cLeave this channel\""
254  "yv 96 string \"%cIgnore spectator chat: %s\""
255  "yv 104 string \"%cIgnore connect msgs: %s\""
256  "yv 112 string \"%cIgnore player chat: %s\""
257  "yv 120 string \"%cIgnore player FOV: %7s\""
258  "yv 128 string \" (use 'set uf %d u' in cfg)\""
259  "yv 144 string2 \"%cExit menu\""
260  "%s xv %d yv 172 string2 " VERSION_STRING;
261  char layout[MAX_STRING_CHARS];
262  char cur[MENU_ITEMS];
263  size_t total;
264 
265  memset(cur, 0x20, sizeof(cur));
266  cur[clamp_menu_cursor(client)] = 0x8d;
267 
268  total = Q_scnprintf(layout, sizeof(layout), format,
269  cur[0], client->target ? "Leave" : "Enter", cur[1],
270  cur[2], MVD_CountClients(client->mvd),
271  cur[3], List_Count(&mvd_channel_list), cur[4],
272  cur[5], (client->uf & UF_MUTE_OBSERVERS) ? YES : NO,
273  cur[6], (client->uf & UF_MUTE_MISC) ? YES : NO,
274  cur[7], (client->uf & UF_MUTE_PLAYERS) ? YES : NO,
275  cur[8], (client->uf & UF_LOCALFOV) ? YES :
276  (client->uf & UF_PLAYERFOV) ? NO " " : DEFAULT,
277  client->uf,
278  cur[9], client->mvd->state == MVD_WAITING ?
279  "xv 0 yv 160 cstring [BUFFERING]" : "",
280  VER_OFS);
281 
282  // send the layout
284  MSG_WriteData(layout, total + 1);
286 
287  client->layout_time = svs.realtime;
288 }

Referenced by MVD_UpdateLayouts().

◆ MVD_LayoutScores()

static void MVD_LayoutScores ( mvd_client_t client)
static

Definition at line 290 of file game.c.

291 {
292  mvd_t *mvd = client->mvd;
293  int flags = MSG_CLEAR | MSG_COMPRESS;
294  char *layout;
295 
296  if (client->layout_type == LAYOUT_OLDSCORES) {
297  layout = mvd->oldscores;
298  } else {
299  layout = mvd->layout;
300  }
301  if (!layout || !layout[0]) {
302  layout = "xv 100 yv 60 string \"<no scoreboard>\"";
303  }
304 
305  // end-of-match scoreboard is reliably delivered
306  if (!client->layout_time || mvd->intermission) {
307  flags |= MSG_RELIABLE;
308  }
309 
310  // send the layout
313  SV_ClientAddMessage(client->cl, flags);
314 
315  client->layout_time = svs.realtime;
316 }

Referenced by MVD_UpdateLayouts().

◆ MVD_LinkEdict()

void MVD_LinkEdict ( mvd_t mvd,
edict_t *  ent 
)

Definition at line 1652 of file game.c.

1653 {
1654  int index;
1655  mmodel_t *cm;
1656  bsp_t *cache = mvd->cm.cache;
1657 
1658  if (!cache) {
1659  return;
1660  }
1661 
1662  if (ent->s.solid == PACKED_BSP) {
1663  index = ent->s.modelindex;
1664  if (index < 1 || index > cache->nummodels) {
1665  Com_WPrintf("%s: entity %d: bad inline model index: %d\n",
1666  __func__, ent->s.number, index);
1667  return;
1668  }
1669  cm = &cache->models[index - 1];
1670  VectorCopy(cm->mins, ent->mins);
1671  VectorCopy(cm->maxs, ent->maxs);
1672  ent->solid = SOLID_BSP;
1673  } else if (ent->s.solid) {
1674  MSG_UnpackSolid16(ent->s.solid, ent->mins, ent->maxs);
1675  ent->solid = SOLID_BBOX;
1676  } else {
1677  VectorClear(ent->mins);
1678  VectorClear(ent->maxs);
1679  ent->solid = SOLID_NOT;
1680  }
1681 
1682  SV_LinkEdict(&mvd->cm, ent);
1683 }

Referenced by MVD_ParsePacketEntities(), MVD_PlayerToEntityStates(), and MVD_Seek_f().

◆ MVD_MostFollowed()

static mvd_player_t* MVD_MostFollowed ( mvd_t mvd)
static

Definition at line 575 of file game.c.

576 {
577  int count[MAX_CLIENTS];
579  mvd_player_t *player, *target = NULL;
580  int i, maxcount = -1;
581 
582  memset(count, 0, sizeof(count));
583 
585  if (other->cl->state == cs_spawned && other->target) {
586  count[other->target - mvd->players]++;
587  }
588  }
589  for (i = 0, player = mvd->players; i < mvd->maxclients; i++, player++) {
590  if (player->inuse && player != mvd->dummy && maxcount < count[i]) {
591  maxcount = count[i];
592  target = player;
593  }
594  }
595  return target;
596 }

Referenced by MVD_GameClientBegin().

◆ MVD_NotifyClient()

static void MVD_NotifyClient ( mvd_client_t client)
static

Definition at line 2149 of file game.c.

2150 {
2151  mvd_t *mvd = client->mvd;
2152 
2153  if (client->notified)
2154  return;
2155 
2156  if (svs.realtime - client->begin_time < 2000)
2157  return;
2158 
2159  // notify them if visibility data is missing
2160  if (!mvd->cm.cache) {
2161  SV_ClientPrintf(client->cl, PRINT_HIGH,
2162  "[MVD] GTV server doesn't have this map!\n");
2163  }
2164 
2165  // notify them if channel is in waiting state
2166  if (mvd->state == MVD_WAITING) {
2167  SV_ClientPrintf(client->cl, PRINT_HIGH,
2168  "[MVD] Buffering data, please wait...\n");
2169  }
2170 
2171  client->notified = qtrue;
2172 }

Referenced by MVD_UpdateClients().

◆ MVD_Observe_f()

static void MVD_Observe_f ( mvd_client_t client)
static

Definition at line 953 of file game.c.

954 {
955  mvd_t *mvd = client->mvd;
956 
957  if (!mvd->players) {
958  SV_ClientPrintf(client->cl, PRINT_HIGH,
959  "[MVD] Please enter a channel first.\n");
960  return;
961  }
962 
963  client->chase_mask = 0;
964  client->chase_auto = qfalse;
965  client->chase_wait = qfalse;
966 
967  if (mvd->intermission) {
968  return;
969  }
970 
971  if (client->target) {
972  MVD_FollowStop(client);
973  return;
974  }
975 
976  if (client->oldtarget && client->oldtarget->inuse) {
977  MVD_FollowStart(client, client->oldtarget);
978  return;
979  }
980 
981  if (!MVD_FollowNext(client, NULL)) {
982  SV_ClientPrintf(client->cl, PRINT_MEDIUM, "[MVD] No players to chase.\n");
983  }
984 }

Referenced by MVD_Follow_f(), MVD_GameClientCommand(), MVD_GameClientThink(), and MVD_Invuse_f().

◆ MVD_PartFilter()

static qboolean MVD_PartFilter ( mvd_client_t client)
static

Definition at line 788 of file game.c.

789 {
790  unsigned i, delta, treshold;
791  float f = mvd_part_filter->value;
792 
793  if (!f) {
794  return qtrue; // show everyone
795  }
796  if (f < 0) {
797  return qfalse; // hide everyone
798  }
799  if (client->admin) {
800  return qtrue; // show admins
801  }
802  if (!client->floodHead) {
803  return qfalse; // not talked yet
804  }
805 
806  // take the most recent sample
807  i = (client->floodHead - 1) & FLOOD_MASK;
808  delta = svs.realtime - client->floodSamples[i];
809  treshold = f * 1000;
810 
811  return delta < treshold;
812 }

Referenced by MVD_GameClientBegin(), MVD_GameClientDisconnect(), MVD_GameClientDrop(), MVD_GameClientNameChanged(), and MVD_TrySwitchChannel().

◆ MVD_PointContents()

static int MVD_PointContents ( vec3_t  p)
static

Definition at line 2025 of file game.c.

2026 {
2027  return 0;
2028 }

Referenced by MVD_GameClientThink().

◆ MVD_PrepWorldFrame()

void MVD_PrepWorldFrame ( void  )

Definition at line 2263 of file game.c.

2264 {
2265  mvd_t *mvd;
2266  edict_t *ent;
2267  int i;
2268 
2269  // reset events and old origins
2270  FOR_EACH_MVD(mvd) {
2271  for (i = 1; i < mvd->pool.num_edicts; i++) {
2272  ent = &mvd->edicts[i];
2273  if (!ent->inuse) {
2274  continue;
2275  }
2276  if (!(ent->s.renderfx & RF_BEAM)) {
2277  VectorCopy(ent->s.origin, ent->s.old_origin);
2278  }
2279  ent->s.event = 0;
2280  }
2281  }
2282 }

Referenced by SV_PrepWorldFrame().

◆ MVD_RemoveClient()

void MVD_RemoveClient ( client_t client)

Definition at line 1685 of file game.c.

1686 {
1687  int index = client - svs.client_pool;
1688  mvd_client_t *cl = &mvd_clients[index];
1689 
1690  List_Remove(&cl->entry);
1691 
1692  memset(cl, 0, sizeof(*cl));
1693  cl->cl = client;
1694 }

Referenced by SV_RemoveClient().

◆ MVD_Say_f()

static void MVD_Say_f ( mvd_client_t client,
int  argnum 
)
static

Definition at line 881 of file game.c.

882 {
883  mvd_t *mvd = client->mvd;
884  unsigned delta, delay = mvd_flood_waitdelay->value * 1000;
885  unsigned treshold = mvd_flood_persecond->value * 1000;
886  char text[150], hightext[150];
888  client_t *cl;
889  unsigned i, j;
890 
891  if (mvd_flood_mute->integer && !client->admin) {
892  SV_ClientPrintf(client->cl, PRINT_HIGH,
893  "[MVD] Spectators may not talk on this server.\n");
894  return;
895  }
896  if (client->uf & UF_MUTE_OBSERVERS) {
897  SV_ClientPrintf(client->cl, PRINT_HIGH,
898  "[MVD] Please turn off ignore mode first.\n");
899  return;
900  }
901 
902  if (client->floodTime) {
903  delta = svs.realtime - client->floodTime;
904  if (delta < delay) {
905  SV_ClientPrintf(client->cl, PRINT_HIGH,
906  "[MVD] You can't talk for %u more seconds.\n",
907  (delay - delta) / 1000);
908  return;
909  }
910  }
911 
913  if (client->floodHead >= j) {
914  i = (client->floodHead - j) & FLOOD_MASK;
915  delta = svs.realtime - client->floodSamples[i];
916  if (delta < treshold) {
917  SV_ClientPrintf(client->cl, PRINT_HIGH,
918  "[MVD] You can't talk for %u seconds.\n", delay / 1000);
919  client->floodTime = svs.realtime;
920  return;
921  }
922  }
923 
924  client->floodSamples[client->floodHead & FLOOD_MASK] = svs.realtime;
925  client->floodHead++;
926 
927  Q_snprintf(text, sizeof(text), "[MVD] %s: %s",
928  client->cl->name, Cmd_ArgsFrom(argnum));
929 
930  // color text for legacy clients
931  for (i = 0; text[i]; i++)
932  hightext[i] = text[i] | 128;
933  hightext[i] = 0;
934 
936  cl = other->cl;
937  if (cl->state < cs_spawned) {
938  continue;
939  }
940  if (!client->admin && (other->uf & UF_MUTE_OBSERVERS)) {
941  continue;
942  }
943 
944  if (cl->protocol == PROTOCOL_VERSION_Q2PRO &&
945  cl->version >= PROTOCOL_VERSION_Q2PRO_SERVER_STATE) {
946  SV_ClientPrintf(cl, PRINT_CHAT, "%s\n", text);
947  } else {
948  SV_ClientPrintf(cl, PRINT_HIGH, "%s\n", hightext);
949  }
950  }
951 }

Referenced by MVD_GameClientCommand().

◆ MVD_SetDefaultLayout()

static void MVD_SetDefaultLayout ( mvd_client_t client)
static

Definition at line 345 of file game.c.

346 {
347  mvd_t *mvd = client->mvd;
348  mvd_layout_t type;
349 
350  if (mvd == &mvd_waitingRoom) {
351  type = LAYOUT_CHANNELS;
352  } else if (mvd->intermission) {
353  type = LAYOUT_SCORES;
354  } else if (client->target && !(mvd->flags & MVF_SINGLEPOV)) {
355  type = LAYOUT_FOLLOW;
356  } else {
357  type = LAYOUT_NONE;
358  }
359 
360  MVD_SetNewLayout(client, type);
361 }

Referenced by MVD_FollowStop(), MVD_GameClientBegin(), MVD_GameClientCommand(), MVD_IntermissionStart(), MVD_Invuse_f(), MVD_SetFollowLayout(), and MVD_ToggleLayout().

◆ MVD_SetFollowLayout()

static void MVD_SetFollowLayout ( mvd_client_t client)
static

Definition at line 372 of file game.c.

373 {
374  if (!client->layout_type) {
375  MVD_SetDefaultLayout(client);
376  } else if (client->layout_type == LAYOUT_FOLLOW) {
377  client->layout_time = 0; // force an update
378  }
379 }

Referenced by MVD_FollowStart(), and MVD_GameClientBegin().

◆ MVD_SetNewLayout()

static void MVD_SetNewLayout ( mvd_client_t client,
mvd_layout_t  type 
)
static

Definition at line 337 of file game.c.

338 {
339  // force an update
340  client->layout_type = type;
341  client->layout_time = 0;
342  client->layout_cursor = 0;
343 }

Referenced by MVD_Invuse_f(), MVD_SetDefaultLayout(), and MVD_ToggleLayout().

◆ MVD_SetPlayer()

static mvd_player_t* MVD_SetPlayer ( mvd_client_t client,
const char *  s 
)
static

Definition at line 986 of file game.c.

987 {
988  mvd_t *mvd = client->mvd;
989  mvd_player_t *player, *match;
990  int i, count;
991 
992  // numeric values are just slot numbers
993  if (COM_IsUint(s)) {
994  i = atoi(s);
995  if (i < 0 || i >= mvd->maxclients) {
996  SV_ClientPrintf(client->cl, PRINT_HIGH,
997  "[MVD] Player slot number %d is invalid.\n", i);
998  return NULL;
999  }
1000 
1001  player = &mvd->players[i];
1002  if (!player->inuse || player == mvd->dummy) {
1003  SV_ClientPrintf(client->cl, PRINT_HIGH,
1004  "[MVD] Player slot number %d is not active.\n", i);
1005  return NULL;
1006  }
1007 
1008  return player;
1009  }
1010 
1011  // check for a name match
1012  match = NULL;
1013  count = 0;
1014  for (i = 0, player = mvd->players; i < mvd->maxclients; i++, player++) {
1015  if (!player->inuse || !player->name[0] || player == mvd->dummy) {
1016  continue;
1017  }
1018  if (!Q_stricmp(player->name, s)) {
1019  return player; // exact match
1020  }
1021  if (Q_stristr(player->name, s)) {
1022  match = player; // partial match
1023  count++;
1024  }
1025  }
1026 
1027  if (!match) {
1028  SV_ClientPrintf(client->cl, PRINT_HIGH,
1029  "[MVD] No players matching '%s' found.\n", s);
1030  return NULL;
1031  }
1032 
1033  if (count > 1) {
1034  SV_ClientPrintf(client->cl, PRINT_HIGH,
1035  "[MVD] '%s' matches multiple players.\n", s);
1036  return NULL;
1037  }
1038 
1039  return match;
1040 }

Referenced by MVD_Follow_f().

◆ MVD_SetPlayerNames()

void MVD_SetPlayerNames ( mvd_t mvd)

Definition at line 1607 of file game.c.

1608 {
1609  int i;
1610 
1611  for (i = 0; i < mvd->maxclients; i++) {
1612  set_player_name(mvd, i);
1613  }
1614 }

Referenced by MVD_ParseServerData(), and MVD_Seek_f().

◆ MVD_SetServerState()

static void MVD_SetServerState ( client_t cl,
mvd_t mvd 
)
static

Definition at line 753 of file game.c.

754 {
755  cl->gamedir = mvd->gamedir;
756  cl->mapname = mvd->mapname;
757  cl->configstrings = (char *)mvd->configstrings;
758  cl->slot = mvd->clientNum;
759  cl->cm = &mvd->cm;
760  cl->pool = &mvd->pool;
761  cl->spawncount = mvd->servercount;
762  cl->maxclients = mvd->maxclients;
763 }

Referenced by MVD_GameClientConnect(), and MVD_SwitchChannel().

◆ MVD_SwitchChannel()

void MVD_SwitchChannel ( mvd_client_t client,
mvd_t mvd 
)

Definition at line 765 of file game.c.

766 {
767  client_t *cl = client->cl;
768 
769  List_Remove(&client->entry);
770  List_SeqAdd(&mvd->clients, &client->entry);
771  client->mvd = mvd;
772  client->begin_time = 0;
773  client->target = NULL;
774  client->oldtarget = NULL;
775  client->chase_mask = 0;
776  client->chase_auto = 0;
777  client->chase_wait = 0;
778  memset(client->chase_bitmap, 0, sizeof(client->chase_bitmap));
780 
781  // needs to reconnect
783  MSG_WriteString(va("changing map=%s; reconnect\n", mvd->mapname));
786 }

Referenced by MVD_Destroy(), and MVD_TrySwitchChannel().

◆ MVD_TestTarget()

static qboolean MVD_TestTarget ( mvd_client_t client,
mvd_player_t target 
)
static

Definition at line 498 of file game.c.

499 {
500  mvd_t *mvd = client->mvd;
501 
502  if (!target)
503  return qfalse;
504 
505  if (!target->inuse)
506  return qfalse;
507 
508  if (target == mvd->dummy)
509  return qfalse;
510 
511  if (!client->chase_auto)
512  return qtrue;
513 
514  return Q_IsBitSet(client->chase_bitmap, target - mvd->players);
515 }

Referenced by MVD_AutoFollow_f(), MVD_FollowNext(), MVD_FollowPrev(), and MVD_UpdateTarget().

◆ MVD_ToggleLayout()

static void MVD_ToggleLayout ( mvd_client_t client,
mvd_layout_t  type 
)
static

Definition at line 363 of file game.c.

364 {
365  if (client->layout_type == type) {
366  MVD_SetDefaultLayout(client);
367  } else {
368  MVD_SetNewLayout(client, type);
369  }
370 }

Referenced by MVD_GameClientCommand().

◆ MVD_Trace()

static trace_t q_gameabi MVD_Trace ( vec3_t  start,
vec3_t  mins,
vec3_t  maxs,
vec3_t  end 
)
static

Definition at line 2014 of file game.c.

2015 {
2016  trace_t trace;
2017 
2018  memset(&trace, 0, sizeof(trace));
2019  VectorCopy(end, trace.endpos);
2020  trace.fraction = 1;
2021 
2022  return trace;
2023 }

Referenced by MVD_GameClientThink().

◆ MVD_TrySwitchChannel()

static void MVD_TrySwitchChannel ( mvd_client_t client,
mvd_t mvd 
)
static

Definition at line 814 of file game.c.

815 {
816  if (mvd == client->mvd) {
817  SV_ClientPrintf(client->cl, PRINT_HIGH,
818  "[MVD] You are already %s.\n", mvd == &mvd_waitingRoom ?
819  "in the Waiting Room" : "on this channel");
820  return; // nothing to do
821  }
822  if (client->begin_time) {
823  if (svs.realtime - client->begin_time < 2000) {
824  SV_ClientPrintf(client->cl, PRINT_HIGH,
825  "[MVD] You may not switch channels too soon.\n");
826  return;
827  }
828  if (MVD_PartFilter(client)) {
829  MVD_BroadcastPrintf(client->mvd, PRINT_MEDIUM, UF_MUTE_MISC,
830  "[MVD] %s left the channel\n", client->cl->name);
831  }
832  }
833 
834  MVD_SwitchChannel(client, mvd);
835 }

Referenced by MVD_GameClientCommand(), MVD_Invuse_f(), and MVD_Join_f().

◆ MVD_UpdateClient()

static void MVD_UpdateClient ( mvd_client_t client)
static

Definition at line 649 of file game.c.

650 {
651  mvd_t *mvd = client->mvd;
652  mvd_player_t *target = client->target;
653  int i;
654 
655  if (!target) {
656  // copy stats of the dummy MVD observer
657  if (mvd->dummy) {
658  for (i = 0; i < MAX_STATS; i++) {
659  client->ps.stats[i] = mvd->dummy->ps.stats[i];
660  }
661  }
662  } else {
663  // copy entire player state
664  client->ps = target->ps;
665  if ((client->uf & UF_LOCALFOV) || (!(client->uf & UF_PLAYERFOV)
666  && client->ps.fov >= 90)) {
667  client->ps.fov = client->fov;
668  }
669  client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
670  client->ps.pmove.pm_type = PM_FREEZE;
671  client->clientNum = target - mvd->players;
672 
673  if (target != mvd->dummy) {
674  if (mvd_stats_hack->integer && mvd->dummy) {
675  // copy stats of the dummy MVD observer
676  for (i = 0; i < MAX_STATS; i++) {
677  if (mvd_stats_hack->integer & (1 << i)) {
678  client->ps.stats[i] = mvd->dummy->ps.stats[i];
679  }
680  }
681  }
682 
683  // chasing someone counts as activity
685  }
686  }
687 
688  // override score
689  switch (mvd_stats_score->integer) {
690  case 0:
691  client->ps.stats[STAT_FRAGS] = 0;
692  break;
693  case 1:
694  client->ps.stats[STAT_FRAGS] = mvd->id;
695  break;
696  }
697 }

Referenced by MVD_FollowStart(), MVD_FollowStop(), MVD_GameClientBegin(), and MVD_UpdateClients().

◆ MVD_UpdateClients()

void MVD_UpdateClients ( mvd_t mvd)

Definition at line 2175 of file game.c.

2176 {
2177  mvd_client_t *client;
2178 
2179  // check for intermission
2180  if (mvd_freeze_hack->integer && mvd->dummy) {
2181  if (!mvd->intermission) {
2182  if (mvd->dummy->ps.pmove.pm_type == PM_FREEZE) {
2184  }
2185  } else if (mvd->dummy->ps.pmove.pm_type != PM_FREEZE) {
2187  }
2188  } else if (mvd->intermission) {
2190  }
2191 
2192  // update UDP clients
2193  FOR_EACH_MVDCL(client, mvd) {
2194  if (client->cl->state == cs_spawned) {
2195  MVD_UpdateTarget(client);
2196  MVD_UpdateClient(client);
2197  MVD_NotifyClient(client);
2198  }
2199  }
2200 }

Referenced by MVD_ParseFrame(), and MVD_Seek_f().

◆ MVD_UpdateConfigstring()

void MVD_UpdateConfigstring ( mvd_t mvd,
int  index 
)

Definition at line 1616 of file game.c.

1617 {
1618  char *s = mvd->configstrings[index];
1619  mvd_client_t *client;
1620 
1621  if (index >= CS_PLAYERSKINS && index < CS_PLAYERSKINS + mvd->maxclients) {
1622  // update player name
1623  update_player_name(mvd, index - CS_PLAYERSKINS);
1624  } else if (index >= CS_GENERAL) {
1625  // reset unicast versions of this string
1626  reset_unicast_strings(mvd, index);
1627  }
1628 
1629  MSG_WriteByte(svc_configstring);
1630  MSG_WriteShort(index);
1631  MSG_WriteString(s);
1632 
1633  // broadcast configstring change
1634  FOR_EACH_MVDCL(client, mvd) {
1635  if (client->cl->state < cs_primed) {
1636  continue;
1637  }
1639  }
1640 
1641  SZ_Clear(&msg_write);
1642 }

Referenced by MVD_ParseConfigstring(), and MVD_Seek_f().

◆ MVD_UpdateLayouts()

static void MVD_UpdateLayouts ( mvd_t mvd)
static

Definition at line 382 of file game.c.

383 {
384  mvd_client_t *client;
385 
386  FOR_EACH_MVDCL(client, mvd) {
387  if (client->cl->state != cs_spawned) {
388  continue;
389  }
390  client->ps.stats[STAT_LAYOUTS] = client->layout_type ? 1 : 0;
391  switch (client->layout_type) {
392  case LAYOUT_FOLLOW:
393  if (!client->layout_time) {
394  MVD_LayoutFollow(client);
395  }
396  break;
397  case LAYOUT_OLDSCORES:
398  case LAYOUT_SCORES:
399  if (!client->layout_time) {
400  MVD_LayoutScores(client);
401  }
402  break;
403  case LAYOUT_MENU:
404  if (mvd->dirty || !client->layout_time) {
405  MVD_LayoutMenu(client);
406  }
407  break;
408  case LAYOUT_CLIENTS:
409  if (svs.realtime - client->layout_time > LAYOUT_MSEC) {
410  MVD_LayoutClients(client);
411  }
412  break;
413  case LAYOUT_CHANNELS:
414  if (mvd_dirty || !client->layout_time) {
415  MVD_LayoutChannels(client);
416  }
417  break;
418  default:
419  break;
420  }
421  }
422 
423  mvd->dirty = qfalse;
424 }

Referenced by MVD_GameRunFrame().

◆ MVD_UpdateTarget()

static void MVD_UpdateTarget ( mvd_client_t client)
static

Definition at line 598 of file game.c.

599 {
600  mvd_t *mvd = client->mvd;
601  mvd_player_t *target;
602  entity_state_t *ent;
603  int i;
604 
605  // find new target for effects auto chasecam
606  if (client->chase_mask && !mvd->intermission) {
607  for (i = 0; i < mvd->maxclients; i++) {
608  target = &mvd->players[i];
609  if (!target->inuse || target == mvd->dummy) {
610  continue;
611  }
612  ent = &mvd->edicts[i + 1].s;
613  if (ent->effects & client->chase_mask) {
614  MVD_FollowStart(client, target);
615  return;
616  }
617  }
618  }
619 
620  // check if current target is still active
621  target = client->target;
622  if (target) {
623  if (target->inuse) {
624  return;
625  }
626  if (!MVD_FollowNext(client, target)) {
627  MVD_FollowStop(client);
628  return;
629  }
630  }
631 
632  // find the next target for auto chasecam
633  target = client->oldtarget;
634  if (client->chase_auto) {
635  if (MVD_TestTarget(client, target)) {
636  MVD_FollowStart(client, target);
637  } else {
638  MVD_FollowNext(client, target);
639  }
640  return;
641  }
642 
643  // if the map has just started, try to return to the previous target
644  if (target && target->inuse && client->chase_wait) {
645  MVD_FollowStart(client, target);
646  }
647 }

Referenced by MVD_AutoFollow_f(), and MVD_UpdateClients().

◆ MVD_WriteDemoMessage()

static void MVD_WriteDemoMessage ( mvd_t mvd)
static

Definition at line 2202 of file game.c.

2203 {
2204  uint16_t msglen;
2205  ssize_t ret;
2206 
2207  msglen = LittleShort(msg_read.cursize);
2208  ret = FS_Write(&msglen, 2, mvd->demorecording);
2209  if (ret != 2)
2210  goto fail;
2211  ret = FS_Write(msg_read.data, msg_read.cursize, mvd->demorecording);
2212  if (ret == msg_read.cursize)
2213  return;
2214 
2215 fail:
2216  Com_EPrintf("[%s] Couldn't write demo: %s\n", mvd->name, Q_ErrorString(ret));
2218 }

Referenced by MVD_GameRunFrame().

◆ print_channel()

static void print_channel ( client_t cl,
mvd_t mvd 
)
static

Definition at line 1351 of file game.c.

1352 {
1353  mvd_player_t *player;
1354  char buffer[MAX_QPATH];
1355  size_t len, total;
1356  int i;
1357 
1358  total = 0;
1359  for (i = 0; i < mvd->maxclients; i++) {
1360  player = &mvd->players[i];
1361  if (!player->inuse || player == mvd->dummy) {
1362  continue;
1363  }
1364  len = strlen(player->name);
1365  if (len == 0) {
1366  continue;
1367  }
1368  if (total + len + 2 >= sizeof(buffer)) {
1369  break;
1370  }
1371  if (total) {
1372  buffer[total + 0] = ',';
1373  buffer[total + 1] = ' ';
1374  total += 2;
1375  }
1376  memcpy(buffer + total, player->name, len);
1377  total += len;
1378  }
1379  buffer[total] = 0;
1380 
1381  SV_ClientPrintf(cl, PRINT_HIGH,
1382  "%2d %-12.12s %-8.8s %3d %3d %s\n", mvd->id,
1383  mvd->name, mvd->mapname,
1384  List_Count(&mvd->clients),
1385  mvd->numplayers, buffer);
1386 }

Referenced by mvd_channel_list_f().

◆ reset_unicast_strings()

static void reset_unicast_strings ( mvd_t mvd,
int  index 
)
static

Definition at line 1551 of file game.c.

1552 {
1553  mvd_cs_t *cs, **next_p;
1554  mvd_player_t *player;
1555  int i;
1556 
1557  for (i = 0; i < mvd->maxclients; i++) {
1558  player = &mvd->players[i];
1559  next_p = &player->configstrings;
1560  for (cs = player->configstrings; cs; cs = cs->next) {
1561  if (cs->index == index) {
1562  Com_DPrintf("%s: reset %d on %d\n", __func__, index, i);
1563  *next_p = cs->next;
1564  Z_Free(cs);
1565  break;
1566  }
1567  next_p = &cs->next;
1568  }
1569  }
1570 }

Referenced by MVD_UpdateConfigstring().

◆ set_player_name()

static void set_player_name ( mvd_t mvd,
int  index 
)
static

Definition at line 1572 of file game.c.

1573 {
1574  mvd_player_t *player;
1575  char *string, *p;
1576 
1577  string = mvd->configstrings[CS_PLAYERSKINS + index];
1578  player = &mvd->players[index];
1579  Q_strlcpy(player->name, string, sizeof(player->name));
1580  p = strchr(player->name, '\\');
1581  if (p) {
1582  *p = 0;
1583  }
1584 }

Referenced by MVD_SetPlayerNames(), and update_player_name().

◆ update_player_name()

static void update_player_name ( mvd_t mvd,
int  index 
)
static

Definition at line 1586 of file game.c.

1587 {
1588  mvd_client_t *client;
1589 
1590  // parse player name
1591  set_player_name(mvd, index);
1592 
1593  // update layouts
1594  FOR_EACH_MVDCL(client, mvd) {
1595  if (client->cl->state < cs_spawned) {
1596  continue;
1597  }
1598  if (client->layout_type != LAYOUT_FOLLOW) {
1599  continue;
1600  }
1601  if (client->target == mvd->players + index) {
1602  client->layout_time = 0;
1603  }
1604  }
1605 }

Referenced by MVD_UpdateConfigstring().

◆ write_cs_list()

static void write_cs_list ( mvd_client_t client,
mvd_cs_t cs 
)
static

Definition at line 435 of file game.c.

436 {
437  for (; cs; cs = cs->next) {
438  MSG_WriteByte(svc_configstring);
439  MSG_WriteShort(cs->index);
440  MSG_WriteString(cs->string);
442  }
443 }

Referenced by MVD_FollowStart(), and MVD_FollowStop().

Variable Documentation

◆ mvd_admin_password

cvar_t* mvd_admin_password
static

Definition at line 25 of file game.c.

Referenced by MVD_Admin_f(), and MVD_GameInit().

◆ mvd_chase_prefix

cvar_t* mvd_chase_prefix
static

Definition at line 35 of file game.c.

Referenced by MVD_GameInit(), and MVD_LayoutFollow().

◆ mvd_clients

mvd_client_t* mvd_clients

Definition at line 37 of file game.c.

Referenced by MVD_GameInit(), MVD_RemoveClient(), and MVD_Shutdown().

◆ mvd_dummy

mvd_player_t mvd_dummy

Definition at line 39 of file game.c.

Referenced by MVD_GameInit().

◆ mvd_filter_version

cvar_t* mvd_filter_version
static

Definition at line 31 of file game.c.

Referenced by MVD_BroadcastPrintf(), and MVD_GameInit().

◆ mvd_flood_msgs

cvar_t* mvd_flood_msgs
static

Definition at line 27 of file game.c.

Referenced by MVD_GameInit(), and MVD_Say_f().

◆ mvd_flood_mute

cvar_t* mvd_flood_mute
static

Definition at line 30 of file game.c.

Referenced by MVD_GameInit(), and MVD_Say_f().

◆ mvd_flood_persecond

cvar_t* mvd_flood_persecond
static

Definition at line 28 of file game.c.

Referenced by MVD_GameInit(), and MVD_Say_f().

◆ mvd_flood_waitdelay

cvar_t* mvd_flood_waitdelay
static

Definition at line 29 of file game.c.

Referenced by MVD_GameInit(), and MVD_Say_f().

◆ mvd_freeze_hack

cvar_t* mvd_freeze_hack
static

Definition at line 34 of file game.c.

Referenced by MVD_GameInit(), and MVD_UpdateClients().

◆ mvd_ge

◆ mvd_numplayers

int mvd_numplayers
static

Definition at line 41 of file game.c.

Referenced by MVD_GameInit(), and MVD_GameRunFrame().

◆ mvd_part_filter

cvar_t* mvd_part_filter
static

Definition at line 26 of file game.c.

Referenced by MVD_GameInit(), and MVD_PartFilter().

◆ mvd_stats_hack

cvar_t* mvd_stats_hack
static

Definition at line 33 of file game.c.

Referenced by MVD_GameInit(), and MVD_UpdateClient().

◆ mvd_stats_score

cvar_t* mvd_stats_score
static

Definition at line 32 of file game.c.

Referenced by MVD_GameInit(), and MVD_UpdateClient().

FLOOD_SAMPLES
#define FLOOD_SAMPLES
Definition: client.h:53
mvd_chase_prefix
static cvar_t * mvd_chase_prefix
Definition: game.c:35
MVD_LayoutScores
static void MVD_LayoutScores(mvd_client_t *client)
Definition: game.c:290
mvd_player_t::configstrings
mvd_cs_t * configstrings
Definition: client.h:66
MVD_Commands_f
static void MVD_Commands_f(mvd_client_t *client)
Definition: game.c:1409
mvd_channel_list
list_t mvd_channel_list
MVD_GameReadGame
static void MVD_GameReadGame(const char *filename)
Definition: game.c:1806
client_state_s::configstrings
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH]
Definition: client.h:289
mvd_client_t::layout_time
unsigned layout_time
Definition: client.h:93
Cvar_Set
cvar_t * Cvar_Set(const char *var_name, const char *value)
Definition: cvar.c:466
CM_BoxTrace
void CM_BoxTrace(trace_t *trace, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, mnode_t *headnode, int brushmask)
Definition: cmodel.c:683
FLOOD_MASK
#define FLOOD_MASK
Definition: client.h:54
mvd_filter_version
static cvar_t * mvd_filter_version
Definition: game.c:31
mvd_layout_t
mvd_layout_t
Definition: client.h:43
set_player_name
static void set_player_name(mvd_t *mvd, int index)
Definition: game.c:1572
MVD_Invuse_f
static void MVD_Invuse_f(mvd_client_t *client)
Definition: game.c:1272
cs_spawned
@ cs_spawned
Definition: server.h:192
mvd_server_t::players
player_packed_t * players
Definition: mvd.c:69
mvd_client_t::chase_bitmap
byte chase_bitmap[MAX_CLIENTS/CHAR_BIT]
Definition: client.h:90
msg_read
sizebuf_t msg_read
Definition: msg.c:37
pm
static pmove_t * pm
Definition: pmove.c:44
mvd_dummy
mvd_player_t mvd_dummy
Definition: game.c:39
mvd_last_activity
unsigned mvd_last_activity
Definition: client.c:106
mvd_waitingRoom
mvd_t mvd_waitingRoom
Definition: client.c:101
VER_OFS
#define VER_OFS
Definition: game.c:56
svs
server_static_t svs
Definition: init.c:21
mvd_client_t::layout_cursor
int layout_cursor
Definition: client.h:94
mvd_client_t::begin_time
unsigned begin_time
Definition: client.h:81
mvd_part_filter
static cvar_t * mvd_part_filter
Definition: game.c:26
MVD_TrySwitchChannel
static void MVD_TrySwitchChannel(mvd_client_t *client, mvd_t *mvd)
Definition: game.c:814
MVD_SetChannel
mvd_t * MVD_SetChannel(int arg)
Definition: client.c:230
maxclients
cvar_t * maxclients
Definition: g_main.c:42
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
MVD_Forward_f
static void MVD_Forward_f(mvd_client_t *client)
Definition: game.c:862
LAYOUT_CHANNELS
@ LAYOUT_CHANNELS
Definition: client.h:50
mvd_client_t::lastcmd
usercmd_t lastcmd
Definition: client.h:100
mvd_client_t::admin
qboolean admin
Definition: client.h:79
MVD_LayoutChannels
static void MVD_LayoutChannels(mvd_client_t *client)
Definition: game.c:148
count_chase_bits
static qboolean count_chase_bits(mvd_client_t *client)
Definition: game.c:1118
MVD_GameInit
static void MVD_GameInit(void)
Definition: game.c:1696
MVD_Shutdown
void MVD_Shutdown(void)
Definition: client.c:2528
MVD_GameClientThink
static void MVD_GameClientThink(edict_t *ent, usercmd_t *cmd)
Definition: game.c:2030
MVD_HitPlayer
static mvd_player_t * MVD_HitPlayer(mvd_client_t *client)
Definition: game.c:1960
MVD_PartFilter
static qboolean MVD_PartFilter(mvd_client_t *client)
Definition: game.c:788
MVD_StopRecord
void MVD_StopRecord(mvd_t *mvd)
Definition: client.c:125
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
mvd_channel_list_f
static void mvd_channel_list_f(mvd_client_t *client)
Definition: game.c:1388
Q_ErrorString
const char * Q_ErrorString(qerror_t error)
Definition: error.c:51
mvd_client_t::chase_mask
int chase_mask
Definition: client.h:87
MVD_TestTarget
static qboolean MVD_TestTarget(mvd_client_t *client, mvd_player_t *target)
Definition: game.c:498
mvd_flood_waitdelay
static cvar_t * mvd_flood_waitdelay
Definition: game.c:29
mvd_clients
mvd_client_t * mvd_clients
Definition: game.c:37
client_s::state
clstate_t state
Definition: server.h:260
MSG_CLEAR
#define MSG_CLEAR
Definition: server.h:215
mvd_cs_s::string
char string[1]
Definition: client.h:59
mvd_client_t::floodTime
unsigned floodTime
Definition: client.h:98
MSG_RELIABLE
#define MSG_RELIABLE
Definition: server.h:214
MVD_GameShutdown
static void MVD_GameShutdown(void)
Definition: game.c:1786
MVD_UpdateTarget
static void MVD_UpdateTarget(mvd_client_t *client)
Definition: game.c:598
MVD_GameClientDisconnect
static void MVD_GameClientDisconnect(edict_t *ent)
Definition: game.c:1947
MVD_SetServerState
static void MVD_SetServerState(client_t *cl, mvd_t *mvd)
Definition: game.c:753
mvd_freeze_hack
static cvar_t * mvd_freeze_hack
Definition: game.c:34
MVD_UpdateLayouts
static void MVD_UpdateLayouts(mvd_t *mvd)
Definition: game.c:382
mvd_client_t::notified
qboolean notified
Definition: client.h:80
MVD_SetFollowLayout
static void MVD_SetFollowLayout(mvd_client_t *client)
Definition: game.c:372
LAYOUT_SCORES
@ LAYOUT_SCORES
Definition: client.h:46
CM_HeadnodeForBox
mnode_t * CM_HeadnodeForBox(vec3_t mins, vec3_t maxs)
Definition: cmodel.c:190
client_state_s::gamedir
char gamedir[MAX_QPATH]
Definition: client.h:277
mvd_client_t::entry
list_t entry
Definition: client.h:76
MVD_GameRunFrame
static void MVD_GameRunFrame(void)
Definition: game.c:2220
SV_InfoSet
#define SV_InfoSet(var, val)
Definition: server.h:73
layout
layout(set=GOD_RAYS_DESC_SET_IDX, binding=0) uniform sampler2DArray TEX_SHADOW_MAP
mvd_client_t::layout_type
mvd_layout_t layout_type
Definition: client.h:92
LAYOUT_CLIENTS
@ LAYOUT_CLIENTS
Definition: client.h:49
mvd_dirty
qboolean mvd_dirty
Definition: client.c:102
Q_vsnprintf
size_t Q_vsnprintf(char *dest, size_t size, const char *fmt, va_list argptr)
Definition: shared.c:791
other
@ other
Definition: ogg.c:63
MVD_FollowNext
static mvd_player_t * MVD_FollowNext(mvd_client_t *client, mvd_player_t *from)
Definition: game.c:517
MVD_GameWriteGame
static void MVD_GameWriteGame(const char *filename, qboolean autosave)
Definition: game.c:1803
FOR_EACH_MVD
#define FOR_EACH_MVD(mvd)
Definition: client.h:26
MSG_WriteByte
void MSG_WriteByte(int c)
Definition: msg.c:107
MVD_GameReadLevel
static void MVD_GameReadLevel(const char *filename)
Definition: game.c:1812
MVD_LayoutMenu
static void MVD_LayoutMenu(mvd_client_t *client)
Definition: game.c:244
Cmd_Argv
char * Cmd_Argv(int arg)
Definition: cmd.c:899
MVD_AutoFollow_f
static void MVD_AutoFollow_f(mvd_client_t *client)
Definition: game.c:1132
svc_stufftext
#define svc_stufftext
Definition: g_local.h:41
MVD_GameServerCommand
static void MVD_GameServerCommand(void)
Definition: game.c:2259
mvd_client_t::uf
int uf
Definition: client.h:83
LAYOUT_FOLLOW
@ LAYOUT_FOLLOW
Definition: client.h:45
Cmd_Argc
int Cmd_Argc(void)
Definition: cmd.c:889
SV_ClientAddMessage
void SV_ClientAddMessage(client_t *client, int flags)
Definition: send.c:399
MVD_ParseEntityString
void MVD_ParseEntityString(mvd_t *mvd, const char *data)
Definition: parse.c:64
mvd_cs_s::index
int index
Definition: client.h:58
mvd_client_t::mvd
struct mvd_s * mvd
Definition: client.h:77
vec3_origin
vec3_t vec3_origin
Definition: shared.c:21
MVD_GameClientCommand
static void MVD_GameClientCommand(edict_t *ent)
Definition: game.c:1424
MVD_FollowStop
static void MVD_FollowStop(mvd_client_t *client)
Definition: game.c:445
mvd_client_t::clientNum
int clientNum
Definition: client.h:73
mvd_s::state
mvd_state_t state
Definition: client.h:130
MVD_Admin_f
static void MVD_Admin_f(mvd_client_t *client)
Definition: game.c:837
Cmd_ArgsFrom
char * Cmd_ArgsFrom(int from)
Definition: cmd.c:981
MSG_COMPRESS
#define MSG_COMPRESS
Definition: server.h:216
BSP_Free
void BSP_Free(bsp_t *bsp)
Definition: bsp.c:932
MVD_GameClientUserinfoChanged
static void MVD_GameClientUserinfoChanged(edict_t *ent, char *userinfo)
Definition: game.c:1904
MVD_SetNewLayout
static void MVD_SetNewLayout(mvd_client_t *client, mvd_layout_t type)
Definition: game.c:337
mvd_player_t::inuse
qboolean inuse
Definition: client.h:64
MENU_ITEMS
#define MENU_ITEMS
Definition: game.c:229
mvd_s
Definition: client.h:127
mvd_active
qboolean mvd_active
Definition: client.c:105
forward
static vec3_t forward
Definition: p_view.c:27
sv
server_t sv
Definition: init.c:22
mvd
static mvd_server_t mvd
Definition: mvd.c:81
PF_Pmove
void PF_Pmove(pmove_t *pm)
Definition: game.c:708
msg_write
sizebuf_t msg_write
Definition: msg.c:34
mvd_client_t::target
mvd_player_t * target
Definition: client.h:85
Com_EndRedirect
void Com_EndRedirect(void)
Definition: common.c:172
Info_ValueForKey
char * Info_ValueForKey(const char *s, const char *key)
Definition: shared.c:945
va
char * va(const char *format,...)
Definition: shared.c:429
Z_Free
void Z_Free(void *ptr)
Definition: zone.c:147
mvd_s::intermission
qboolean intermission
Definition: client.h:172
server_static_s::client_pool
client_t * client_pool
Definition: server.h:456
MVD_PointContents
static int MVD_PointContents(vec3_t p)
Definition: game.c:2025
SV_ClientCommand
void SV_ClientCommand(client_t *client, const char *fmt,...)
Definition: send.c:185
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: shared.c:23
LAYOUT_NONE
@ LAYOUT_NONE
Definition: client.h:44
mvd_stats_score
static cvar_t * mvd_stats_score
Definition: game.c:32
MVD_FEATURES
#define MVD_FEATURES
Definition: client.h:39
Q_strlcpy
size_t Q_strlcpy(char *dst, const char *src, size_t size)
Definition: shared.c:715
MVD_SetDefaultLayout
static void MVD_SetDefaultLayout(mvd_client_t *client)
Definition: game.c:345
mvd_flood_mute
static cvar_t * mvd_flood_mute
Definition: game.c:30
MVD_CountClients
static int MVD_CountClients(mvd_t *mvd)
Definition: game.c:135
Z_ReservedAllocz
void * Z_ReservedAllocz(size_t size)
Definition: zone.c:367
mvd_client_t::oldtarget
mvd_player_t * oldtarget
Definition: client.h:86
MVD_BroadcastPrintf
void MVD_BroadcastPrintf(mvd_t *mvd, int level, int mask, const char *fmt,...)
Definition: game.c:707
mvd_client_t::cl
client_t * cl
Definition: client.h:78
MSG_WriteShort
void MSG_WriteShort(int c)
Definition: msg.c:125
print_channel
static void print_channel(client_t *cl, mvd_t *mvd)
Definition: game.c:1351
MVD_FollowStart
static void MVD_FollowStart(mvd_client_t *client, mvd_player_t *target)
Definition: game.c:480
SV_LinkEdict
void SV_LinkEdict(cm_t *cm, edict_t *ent)
Definition: world.c:156
MVD_WAITING
@ MVD_WAITING
Definition: client.h:109
CM_TransformedBoxTrace
void CM_TransformedBoxTrace(trace_t *trace, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, mnode_t *headnode, int brushmask, vec3_t origin, vec3_t angles)
Definition: cmodel.c:764
mvd_numplayers
static int mvd_numplayers
Definition: game.c:41
EDICT_MVDCL
#define EDICT_MVDCL(ent)
Definition: client.h:32
mvd_client_t
Definition: client.h:69
MVD_NotifyClient
static void MVD_NotifyClient(mvd_client_t *client)
Definition: game.c:2149
mvd_client_t::jump_held
int jump_held
Definition: client.h:102
client_state_s::mapname
char mapname[MAX_QPATH]
Definition: client.h:290
Com_WildCmpEx
qboolean Com_WildCmpEx(const char *filter, const char *string, int term, qboolean ignorecase)
Definition: utils.c:122
FOR_EACH_MVDCL
#define FOR_EACH_MVDCL(cl, mvd)
Definition: client.h:29
mvd_client_t::ps
player_state_t ps
Definition: client.h:71
LAYOUT_MENU
@ LAYOUT_MENU
Definition: client.h:48
MVD_FollowPrev
static mvd_player_t * MVD_FollowPrev(mvd_client_t *client, mvd_player_t *from)
Definition: game.c:546
Z_TagReserve
void Z_TagReserve(size_t size, memtag_t tag)
Definition: zone.c:342
cl
client_state_t cl
Definition: main.c:99
MVD_ToggleLayout
static void MVD_ToggleLayout(mvd_client_t *client, mvd_layout_t type)
Definition: game.c:363
mvd_stats_hack
static cvar_t * mvd_stats_hack
Definition: game.c:33
FS_Write
ssize_t FS_Write(const void *buf, size_t len, qhandle_t f)
Definition: files.c:1643
mvd_client_t::floodSamples
unsigned floodSamples[FLOOD_SAMPLES]
Definition: client.h:96
mvd_cs_s
Definition: client.h:56
mvd_server_t::dummy
client_t * dummy
Definition: mvd.c:57
reset_unicast_strings
static void reset_unicast_strings(mvd_t *mvd, int index)
Definition: game.c:1551
mvd_client_t::chase_auto
qboolean chase_auto
Definition: client.h:88
mvd_jmpbuf
jmp_buf mvd_jmpbuf
Definition: client.c:108
COM_IsUint
qboolean COM_IsUint(const char *s)
Definition: shared.c:330
MSG_WriteString
void MSG_WriteString(const char *string)
Definition: msg.c:160
c
statCounters_t c
Definition: main.c:30
DEFAULT
#define DEFAULT
Definition: game.c:232
MVD_UpdateClient
static void MVD_UpdateClient(mvd_client_t *client)
Definition: game.c:649
mvd_client_t::chase_wait
qboolean chase_wait
Definition: client.h:89
mvd_player_t
Definition: client.h:62
MVD_IntermissionStart
static void MVD_IntermissionStart(mvd_t *mvd)
Definition: game.c:2093
Cvar_ClampInteger
int Cvar_ClampInteger(cvar_t *var, int min, int max)
Definition: cvar.c:549
server_static_s::realtime
unsigned realtime
Definition: server.h:454
LAYOUT_OLDSCORES
@ LAYOUT_OLDSCORES
Definition: client.h:47
mvd_cs_s::next
struct mvd_cs_s * next
Definition: client.h:57
level
level_locals_t level
Definition: g_main.c:22
NO
#define NO
Definition: game.c:231
mvd_flood_msgs
static cvar_t * mvd_flood_msgs
Definition: game.c:27
cs_primed
@ cs_primed
Definition: server.h:191
SV_ClientPrintf
void SV_ClientPrintf(client_t *client, int level, const char *fmt,...)
Definition: send.c:121
mvd_client_t::floodHead
unsigned floodHead
Definition: client.h:97
MVD_WriteDemoMessage
static void MVD_WriteDemoMessage(mvd_t *mvd)
Definition: game.c:2202
update_player_name
static void update_player_name(mvd_t *mvd, int index)
Definition: game.c:1586
mvd_player_t::name
char name[16]
Definition: client.h:65
MVD_GameWriteLevel
static void MVD_GameWriteLevel(const char *filename)
Definition: game.c:1809
MVD_MostFollowed
static mvd_player_t * MVD_MostFollowed(mvd_t *mvd)
Definition: game.c:575
client_s
Definition: server.h:256
client_s::netchan
netchan_t * netchan
Definition: server.h:357
MVD_IntermissionStop
static void MVD_IntermissionStop(mvd_t *mvd)
Definition: game.c:2121
svc_layout
#define svc_layout
Definition: g_local.h:39
mvd_ge
game_export_t mvd_ge
Definition: game.c:2285
MVD_GameClientBegin
static void MVD_GameClientBegin(edict_t *ent)
Definition: game.c:1840
LAYOUT_MSEC
#define LAYOUT_MSEC
Definition: client.h:41
BSP_Load
qerror_t BSP_Load(const char *name, bsp_t **bsp_p)
Definition: bsp.c:1087
PAGE_CLIENTS
#define PAGE_CLIENTS
Definition: game.c:54
MVD_LayoutFollow
static void MVD_LayoutFollow(mvd_client_t *client)
Definition: game.c:318
MVD_Say_f
static void MVD_Say_f(mvd_client_t *client, int argnum)
Definition: game.c:881
mvd_admin_password
static cvar_t * mvd_admin_password
Definition: game.c:25
MVD_Join_f
static void MVD_Join_f(mvd_client_t *client)
Definition: game.c:1331
mvd_client_t::fov
float fov
Definition: client.h:82
MVD_GameSpawnEntities
static void MVD_GameSpawnEntities(const char *mapname, const char *entstring, const char *spawnpoint)
Definition: game.c:1800
mvd_flood_persecond
static cvar_t * mvd_flood_persecond
Definition: game.c:28
MVD_Observe_f
static void MVD_Observe_f(mvd_client_t *client)
Definition: game.c:953
server_t::spawncount
int spawncount
Definition: server.h:147
MVD_LayoutClients
static void MVD_LayoutClients(mvd_client_t *client)
Definition: game.c:58
MVD_SwitchChannel
void MVD_SwitchChannel(mvd_client_t *client, mvd_t *mvd)
Definition: game.c:765
client_state_s::maxclients
int maxclients
Definition: client.h:279
MVD_Clients_f
static void MVD_Clients_f(mvd_client_t *client)
Definition: game.c:1401
YES
#define YES
Definition: game.c:230
Q_scnprintf
size_t Q_scnprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:867
mvd_player_t::ps
player_state_t ps
Definition: client.h:63
MVD_Trace
static trace_t q_gameabi MVD_Trace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
Definition: game.c:2014
client_s::configstrings
char * configstrings
Definition: server.h:343
MVD_Follow_f
static void MVD_Follow_f(mvd_client_t *client)
Definition: game.c:1042
MVD_SetPlayer
static mvd_player_t * MVD_SetPlayer(mvd_client_t *client, const char *s)
Definition: game.c:986
MVD_InfoSet
#define MVD_InfoSet(var, val)
Definition: client.h:35
clamp_menu_cursor
static int clamp_menu_cursor(mvd_client_t *client)
Definition: game.c:234
SZ_Clear
void SZ_Clear(sizebuf_t *buf)
Definition: sizebuf.c:40
mvd_server_t::clients
gtv_client_t * clients
Definition: mvd.c:78
SV_ClientReset
void SV_ClientReset(client_t *client)
Definition: init.c:24
SV_ClientRedirect
#define SV_ClientRedirect()
Definition: server.h:584
MVD_GameClientConnect
static qboolean MVD_GameClientConnect(edict_t *ent, char *userinfo)
Definition: game.c:1816
write_cs_list
static void write_cs_list(mvd_client_t *client, mvd_cs_t *cs)
Definition: game.c:435
client_s::name
char name[MAX_CLIENT_NAME]
Definition: server.h:276
sv_maxclients
cvar_t * sv_maxclients
Definition: main.c:58