2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 extern cvar_t pausable
;
27 void Mod_Print (void);
35 extern void M_Menu_Quit_f (void);
37 void Host_Quit_f (void)
39 if (key_dest
!= key_console
&& cls
.state
!= ca_dedicated
)
45 Host_ShutdownServer(false);
56 void Host_Status_f (void)
63 void (*print
) (char *fmt
, ...);
65 if (cmd_source
== src_command
)
69 Cmd_ForwardToServer ();
75 print
= SV_ClientPrintf
;
77 print ("host: %s\n", Cvar_VariableString ("hostname"));
78 print ("version: %4.2f\n", VERSION
);
80 print ("tcp/ip: %s\n", my_tcpip_address
);
82 print ("ipx: %s\n", my_ipx_address
);
83 print ("map: %s\n", sv
.name
);
84 print ("players: %i active (%i max)\n\n", net_activeconnections
, svs
.maxclients
);
85 for (j
=0, client
= svs
.clients
; j
<svs
.maxclients
; j
++, client
++)
89 seconds
= (int)(net_time
- client
->netconnection
->connecttime
);
90 minutes
= seconds
/ 60;
93 seconds
-= (minutes
* 60);
96 minutes
-= (hours
* 60);
100 print ("#%-2u %-16.16s %3i %2i:%02i:%02i\n", j
+1, client
->name
, (int)client
->edict
->v
.frags
, hours
, minutes
, seconds
);
101 print (" %s\n", client
->netconnection
->address
);
110 Sets client to godmode
113 void Host_God_f (void)
115 if (cmd_source
== src_command
)
117 Cmd_ForwardToServer ();
121 if (pr_global_struct
->deathmatch
&& !host_client
->privileged
)
124 sv_player
->v
.flags
= (int)sv_player
->v
.flags
^ FL_GODMODE
;
125 if (!((int)sv_player
->v
.flags
& FL_GODMODE
) )
126 SV_ClientPrintf ("godmode OFF\n");
128 SV_ClientPrintf ("godmode ON\n");
131 void Host_Notarget_f (void)
133 if (cmd_source
== src_command
)
135 Cmd_ForwardToServer ();
139 if (pr_global_struct
->deathmatch
&& !host_client
->privileged
)
142 sv_player
->v
.flags
= (int)sv_player
->v
.flags
^ FL_NOTARGET
;
143 if (!((int)sv_player
->v
.flags
& FL_NOTARGET
) )
144 SV_ClientPrintf ("notarget OFF\n");
146 SV_ClientPrintf ("notarget ON\n");
149 qboolean noclip_anglehack
;
151 void Host_Noclip_f (void)
153 if (cmd_source
== src_command
)
155 Cmd_ForwardToServer ();
159 if (pr_global_struct
->deathmatch
&& !host_client
->privileged
)
162 if (sv_player
->v
.movetype
!= MOVETYPE_NOCLIP
)
164 noclip_anglehack
= true;
165 sv_player
->v
.movetype
= MOVETYPE_NOCLIP
;
166 SV_ClientPrintf ("noclip ON\n");
170 noclip_anglehack
= false;
171 sv_player
->v
.movetype
= MOVETYPE_WALK
;
172 SV_ClientPrintf ("noclip OFF\n");
180 Sets client to flymode
183 void Host_Fly_f (void)
185 if (cmd_source
== src_command
)
187 Cmd_ForwardToServer ();
191 if (pr_global_struct
->deathmatch
&& !host_client
->privileged
)
194 if (sv_player
->v
.movetype
!= MOVETYPE_FLY
)
196 sv_player
->v
.movetype
= MOVETYPE_FLY
;
197 SV_ClientPrintf ("flymode ON\n");
201 sv_player
->v
.movetype
= MOVETYPE_WALK
;
202 SV_ClientPrintf ("flymode OFF\n");
213 void Host_Ping_f (void)
219 if (cmd_source
== src_command
)
221 Cmd_ForwardToServer ();
225 SV_ClientPrintf ("Client ping times:\n");
226 for (i
=0, client
= svs
.clients
; i
<svs
.maxclients
; i
++, client
++)
231 for (j
=0 ; j
<NUM_PING_TIMES
; j
++)
232 total
+=client
->ping_times
[j
];
233 total
/= NUM_PING_TIMES
;
234 SV_ClientPrintf ("%4i %s\n", (int)(total
*1000), client
->name
);
239 ===============================================================================
243 ===============================================================================
248 ======================
253 command from the console. Active clients are kicked off.
254 ======================
256 void Host_Map_f (void)
259 char name
[MAX_QPATH
];
261 if (cmd_source
!= src_command
)
264 cls
.demonum
= -1; // stop demo loop in case this fails
267 Host_ShutdownServer(false);
269 key_dest
= key_game
; // remove console or menu
270 SCR_BeginLoadingPlaque ();
272 cls
.mapstring
[0] = 0;
273 for (i
=0 ; i
<Cmd_Argc() ; i
++)
275 strcat (cls
.mapstring
, Cmd_Argv(i
));
276 strcat (cls
.mapstring
, " ");
278 strcat (cls
.mapstring
, "\n");
280 svs
.serverflags
= 0; // haven't completed an episode yet
281 strcpy (name
, Cmd_Argv(1));
283 SV_SpawnServer (name
, NULL
);
285 SV_SpawnServer (name
);
290 if (cls
.state
!= ca_dedicated
)
292 strcpy (cls
.spawnparms
, "");
294 for (i
=2 ; i
<Cmd_Argc() ; i
++)
296 strcat (cls
.spawnparms
, Cmd_Argv(i
));
297 strcat (cls
.spawnparms
, " ");
300 Cmd_ExecuteString ("connect local", src_command
);
308 Goes to a new map, taking all clients along
311 void Host_Changelevel_f (void)
314 char level
[MAX_QPATH
];
315 char _startspot
[MAX_QPATH
];
320 Con_Printf ("changelevel <levelname> : continue game on a new level\n");
323 if (!sv
.active
|| cls
.demoplayback
)
325 Con_Printf ("Only the server may changelevel\n");
329 strcpy (level
, Cmd_Argv(1));
334 strcpy (_startspot
, Cmd_Argv(2));
335 startspot
= _startspot
;
338 SV_SaveSpawnparms ();
339 SV_SpawnServer (level
, startspot
);
341 char level
[MAX_QPATH
];
345 Con_Printf ("changelevel <levelname> : continue game on a new level\n");
348 if (!sv
.active
|| cls
.demoplayback
)
350 Con_Printf ("Only the server may changelevel\n");
353 SV_SaveSpawnparms ();
354 strcpy (level
, Cmd_Argv(1));
355 SV_SpawnServer (level
);
363 Restarts the current server for a dead player
366 void Host_Restart_f (void)
368 char mapname
[MAX_QPATH
];
370 char startspot
[MAX_QPATH
];
373 if (cls
.demoplayback
|| !sv
.active
)
376 if (cmd_source
!= src_command
)
378 strcpy (mapname
, sv
.name
); // must copy out, because it gets cleared
381 strcpy(startspot
, sv
.startspot
);
382 SV_SpawnServer (mapname
, startspot
);
384 SV_SpawnServer (mapname
);
392 This command causes the client to wait for the signon messages again.
393 This is sent just before a server changes levels
396 void Host_Reconnect_f (void)
398 SCR_BeginLoadingPlaque ();
399 cls
.signon
= 0; // need new connection messages
403 =====================
406 User command to connect to server
407 =====================
409 void Host_Connect_f (void)
411 char name
[MAX_QPATH
];
413 cls
.demonum
= -1; // stop demo loop in case this fails
414 if (cls
.demoplayback
)
419 strcpy (name
, Cmd_Argv(1));
420 CL_EstablishConnection (name
);
426 ===============================================================================
430 ===============================================================================
433 #define SAVEGAME_VERSION 5
439 Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current
442 void Host_SavegameComment (char *text
)
447 for (i
=0 ; i
<SAVEGAME_COMMENT_LENGTH
; i
++)
449 memcpy (text
, cl
.levelname
, strlen(cl
.levelname
));
450 sprintf (kills
,"kills:%3i/%3i", cl
.stats
[STAT_MONSTERS
], cl
.stats
[STAT_TOTALMONSTERS
]);
451 memcpy (text
+22, kills
, strlen(kills
));
452 // convert space to _ to make stdio happy
453 for (i
=0 ; i
<SAVEGAME_COMMENT_LENGTH
; i
++)
456 text
[SAVEGAME_COMMENT_LENGTH
] = '\0';
465 void Host_Savegame_f (void)
470 char comment
[SAVEGAME_COMMENT_LENGTH
+1];
472 if (cmd_source
!= src_command
)
477 Con_Printf ("Not playing a local game.\n");
483 Con_Printf ("Can't save in intermission.\n");
487 if (svs
.maxclients
!= 1)
489 Con_Printf ("Can't save multiplayer games.\n");
495 Con_Printf ("save <savename> : save a game\n");
499 if (strstr(Cmd_Argv(1), ".."))
501 Con_Printf ("Relative pathnames are not allowed.\n");
505 for (i
=0 ; i
<svs
.maxclients
; i
++)
507 if (svs
.clients
[i
].active
&& (svs
.clients
[i
].edict
->v
.health
<= 0) )
509 Con_Printf ("Can't savegame with a dead player\n");
514 sprintf (name
, "%s/%s", com_gamedir
, Cmd_Argv(1));
515 COM_DefaultExtension (name
, ".sav");
517 Con_Printf ("Saving game to %s...\n", name
);
518 f
= fopen (name
, "w");
521 Con_Printf ("ERROR: couldn't open.\n");
525 fprintf (f
, "%i\n", SAVEGAME_VERSION
);
526 Host_SavegameComment (comment
);
527 fprintf (f
, "%s\n", comment
);
528 for (i
=0 ; i
<NUM_SPAWN_PARMS
; i
++)
529 fprintf (f
, "%f\n", svs
.clients
->spawn_parms
[i
]);
530 fprintf (f
, "%d\n", current_skill
);
531 fprintf (f
, "%s\n", sv
.name
);
532 fprintf (f
, "%f\n",sv
.time
);
534 // write the light styles
536 for (i
=0 ; i
<MAX_LIGHTSTYLES
; i
++)
538 if (sv
.lightstyles
[i
])
539 fprintf (f
, "%s\n", sv
.lightstyles
[i
]);
546 for (i
=0 ; i
<sv
.num_edicts
; i
++)
548 ED_Write (f
, EDICT_NUM(i
));
552 Con_Printf ("done.\n");
561 void Host_Loadgame_f (void)
563 char name
[MAX_OSPATH
];
565 char mapname
[MAX_QPATH
];
567 char str
[32768], *start
;
572 float spawn_parms
[NUM_SPAWN_PARMS
];
574 if (cmd_source
!= src_command
)
579 Con_Printf ("load <savename> : load a game\n");
583 cls
.demonum
= -1; // stop demo loop in case this fails
585 sprintf (name
, "%s/%s", com_gamedir
, Cmd_Argv(1));
586 COM_DefaultExtension (name
, ".sav");
588 // we can't call SCR_BeginLoadingPlaque, because too much stack space has
589 // been used. The menu calls it before stuffing loadgame command
590 // SCR_BeginLoadingPlaque ();
592 Con_Printf ("Loading game from %s...\n", name
);
593 f
= fopen (name
, "r");
596 Con_Printf ("ERROR: couldn't open.\n");
600 fscanf (f
, "%i\n", &version
);
601 if (version
!= SAVEGAME_VERSION
)
604 Con_Printf ("Savegame is version %i, not %i\n", version
, SAVEGAME_VERSION
);
607 fscanf (f
, "%s\n", str
);
608 for (i
=0 ; i
<NUM_SPAWN_PARMS
; i
++)
609 fscanf (f
, "%f\n", &spawn_parms
[i
]);
610 // this silliness is so we can load 1.06 save files, which have float skill values
611 fscanf (f
, "%f\n", &tfloat
);
612 current_skill
= (int)(tfloat
+ 0.1);
613 Cvar_SetValue ("skill", (float)current_skill
);
616 Cvar_SetValue ("deathmatch", 0);
617 Cvar_SetValue ("coop", 0);
618 Cvar_SetValue ("teamplay", 0);
621 fscanf (f
, "%s\n",mapname
);
622 fscanf (f
, "%f\n",&time
);
627 SV_SpawnServer (mapname
, NULL
);
629 SV_SpawnServer (mapname
);
633 Con_Printf ("Couldn't load map\n");
636 sv
.paused
= true; // pause until all clients connect
639 // load the light styles
641 for (i
=0 ; i
<MAX_LIGHTSTYLES
; i
++)
643 fscanf (f
, "%s\n", str
);
644 sv
.lightstyles
[i
] = Hunk_Alloc (strlen(str
)+1);
645 strcpy (sv
.lightstyles
[i
], str
);
648 // load the edicts out of the savegame file
649 entnum
= -1; // -1 is the globals
652 for (i
=0 ; i
<sizeof(str
)-1 ; i
++)
664 if (i
== sizeof(str
)-1)
665 Sys_Error ("Loadgame buffer overflow");
668 start
= COM_Parse(str
);
670 break; // end of file
671 if (strcmp(com_token
,"{"))
672 Sys_Error ("First token isn't a brace");
675 { // parse the global vars
676 ED_ParseGlobals (start
);
681 ent
= EDICT_NUM(entnum
);
682 memset (&ent
->v
, 0, progs
->entityfields
* 4);
684 ED_ParseEdict (start
, ent
);
686 // link it into the bsp tree
688 SV_LinkEdict (ent
, false);
694 sv
.num_edicts
= entnum
;
699 for (i
=0 ; i
<NUM_SPAWN_PARMS
; i
++)
700 svs
.clients
->spawn_parms
[i
] = spawn_parms
[i
];
702 if (cls
.state
!= ca_dedicated
)
704 CL_EstablishConnection ("local");
715 char comment
[SAVEGAME_COMMENT_LENGTH
+1];
718 sprintf (name
, "%s/%s.gip", com_gamedir
, sv
.name
);
720 Con_Printf ("Saving game to %s...\n", name
);
721 f
= fopen (name
, "w");
724 Con_Printf ("ERROR: couldn't open.\n");
728 fprintf (f
, "%i\n", SAVEGAME_VERSION
);
729 Host_SavegameComment (comment
);
730 fprintf (f
, "%s\n", comment
);
731 // for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
732 // fprintf (f, "%f\n", svs.clients->spawn_parms[i]);
733 fprintf (f
, "%f\n", skill
.value
);
734 fprintf (f
, "%s\n", sv
.name
);
735 fprintf (f
, "%f\n", sv
.time
);
737 // write the light styles
739 for (i
=0 ; i
<MAX_LIGHTSTYLES
; i
++)
741 if (sv
.lightstyles
[i
])
742 fprintf (f
, "%s\n", sv
.lightstyles
[i
]);
748 for (i
=svs
.maxclients
+1 ; i
<sv
.num_edicts
; i
++)
751 if ((int)ent
->v
.flags
& FL_ARCHIVE_OVERRIDE
)
753 fprintf (f
, "%i\n",i
);
758 Con_Printf ("done.\n");
761 int LoadGamestate(char *level
, char *startspot
)
763 char name
[MAX_OSPATH
];
765 char mapname
[MAX_QPATH
];
767 char str
[32768], *start
;
772 // float spawn_parms[NUM_SPAWN_PARMS];
774 sprintf (name
, "%s/%s.gip", com_gamedir
, level
);
776 Con_Printf ("Loading game from %s...\n", name
);
777 f
= fopen (name
, "r");
780 Con_Printf ("ERROR: couldn't open.\n");
784 fscanf (f
, "%i\n", &version
);
785 if (version
!= SAVEGAME_VERSION
)
788 Con_Printf ("Savegame is version %i, not %i\n", version
, SAVEGAME_VERSION
);
791 fscanf (f
, "%s\n", str
);
792 // for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
793 // fscanf (f, "%f\n", &spawn_parms[i]);
794 fscanf (f
, "%f\n", &sk
);
795 Cvar_SetValue ("skill", sk
);
797 fscanf (f
, "%s\n",mapname
);
798 fscanf (f
, "%f\n",&time
);
800 SV_SpawnServer (mapname
, startspot
);
804 Con_Printf ("Couldn't load map\n");
808 // load the light styles
809 for (i
=0 ; i
<MAX_LIGHTSTYLES
; i
++)
811 fscanf (f
, "%s\n", str
);
812 sv
.lightstyles
[i
] = Hunk_Alloc (strlen(str
)+1);
813 strcpy (sv
.lightstyles
[i
], str
);
816 // load the edicts out of the savegame file
819 fscanf (f
, "%i\n",&entnum
);
820 for (i
=0 ; i
<sizeof(str
)-1 ; i
++)
832 if (i
== sizeof(str
)-1)
833 Sys_Error ("Loadgame buffer overflow");
836 start
= COM_Parse(str
);
838 break; // end of file
839 if (strcmp(com_token
,"{"))
840 Sys_Error ("First token isn't a brace");
844 ent
= EDICT_NUM(entnum
);
845 memset (&ent
->v
, 0, progs
->entityfields
* 4);
847 ED_ParseEdict (start
, ent
);
849 // link it into the bsp tree
851 SV_LinkEdict (ent
, false);
854 // sv.num_edicts = entnum;
858 // for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
859 // svs.clients->spawn_parms[i] = spawn_parms[i];
864 // changing levels within a unit
865 void Host_Changelevel2_f (void)
867 char level
[MAX_QPATH
];
868 char _startspot
[MAX_QPATH
];
873 Con_Printf ("changelevel2 <levelname> : continue game on a new level in the unit\n");
876 if (!sv
.active
|| cls
.demoplayback
)
878 Con_Printf ("Only the server may changelevel\n");
882 strcpy (level
, Cmd_Argv(1));
887 strcpy (_startspot
, Cmd_Argv(2));
888 startspot
= _startspot
;
891 SV_SaveSpawnparms ();
893 // save the current level's state
896 // try to restore the new level
897 if (LoadGamestate (level
, startspot
))
898 SV_SpawnServer (level
, startspot
);
903 //============================================================================
906 ======================
908 ======================
910 void Host_Name_f (void)
914 if (Cmd_Argc () == 1)
916 Con_Printf ("\"name\" is \"%s\"\n", cl_name
.string
);
919 if (Cmd_Argc () == 2)
920 newName
= Cmd_Argv(1);
922 newName
= Cmd_Args();
925 if (cmd_source
== src_command
)
927 if (Q_strcmp(cl_name
.string
, newName
) == 0)
929 Cvar_Set ("_cl_name", newName
);
930 if (cls
.state
== ca_connected
)
931 Cmd_ForwardToServer ();
935 if (host_client
->name
[0] && strcmp(host_client
->name
, "unconnected") )
936 if (Q_strcmp(host_client
->name
, newName
) != 0)
937 Con_Printf ("%s renamed to %s\n", host_client
->name
, newName
);
938 Q_strcpy (host_client
->name
, newName
);
939 host_client
->edict
->v
.netname
= host_client
->name
- pr_strings
;
941 // send notification to all clients
943 MSG_WriteByte (&sv
.reliable_datagram
, svc_updatename
);
944 MSG_WriteByte (&sv
.reliable_datagram
, host_client
- svs
.clients
);
945 MSG_WriteString (&sv
.reliable_datagram
, host_client
->name
);
949 void Host_Version_f (void)
951 Con_Printf ("Version %4.2f\n", VERSION
);
952 Con_Printf ("Exe: "__TIME__
" "__DATE__
"\n");
956 void Host_Please_f (void)
961 if (cmd_source
!= src_command
)
964 if ((Cmd_Argc () == 3) && Q_strcmp(Cmd_Argv(1), "#") == 0)
966 j
= Q_atof(Cmd_Argv(2)) - 1;
967 if (j
< 0 || j
>= svs
.maxclients
)
969 if (!svs
.clients
[j
].active
)
971 cl
= &svs
.clients
[j
];
974 cl
->privileged
= false;
975 cl
->edict
->v
.flags
= (int)cl
->edict
->v
.flags
& ~(FL_GODMODE
|FL_NOTARGET
);
976 cl
->edict
->v
.movetype
= MOVETYPE_WALK
;
977 noclip_anglehack
= false;
980 cl
->privileged
= true;
983 if (Cmd_Argc () != 2)
986 for (j
=0, cl
= svs
.clients
; j
<svs
.maxclients
; j
++, cl
++)
990 if (Q_strcasecmp(cl
->name
, Cmd_Argv(1)) == 0)
994 cl
->privileged
= false;
995 cl
->edict
->v
.flags
= (int)cl
->edict
->v
.flags
& ~(FL_GODMODE
|FL_NOTARGET
);
996 cl
->edict
->v
.movetype
= MOVETYPE_WALK
;
997 noclip_anglehack
= false;
1000 cl
->privileged
= true;
1008 void Host_Say(qboolean teamonly
)
1014 unsigned char text
[64];
1015 qboolean fromServer
= false;
1017 if (cmd_source
== src_command
)
1019 if (cls
.state
== ca_dedicated
)
1026 Cmd_ForwardToServer ();
1031 if (Cmd_Argc () < 2)
1037 // remove quotes if present
1041 p
[Q_strlen(p
)-1] = 0;
1044 // turn on color set 1
1046 sprintf (text
, "%c%s: ", 1, save
->name
);
1048 sprintf (text
, "%c<%s> ", 1, hostname
.string
);
1050 j
= sizeof(text
) - 2 - Q_strlen(text
); // -2 for /n and null terminator
1051 if (Q_strlen(p
) > j
)
1055 strcat (text
, "\n");
1057 for (j
= 0, client
= svs
.clients
; j
< svs
.maxclients
; j
++, client
++)
1059 if (!client
|| !client
->active
|| !client
->spawned
)
1061 if (teamplay
.value
&& teamonly
&& client
->edict
->v
.team
!= save
->edict
->v
.team
)
1063 host_client
= client
;
1064 SV_ClientPrintf("%s", text
);
1068 Sys_Printf("%s", &text
[1]);
1072 void Host_Say_f(void)
1078 void Host_Say_Team_f(void)
1084 void Host_Tell_f(void)
1092 if (cmd_source
== src_command
)
1094 Cmd_ForwardToServer ();
1098 if (Cmd_Argc () < 3)
1101 Q_strcpy(text
, host_client
->name
);
1102 Q_strcat(text
, ": ");
1106 // remove quotes if present
1110 p
[Q_strlen(p
)-1] = 0;
1113 // check length & truncate if necessary
1114 j
= sizeof(text
) - 2 - Q_strlen(text
); // -2 for /n and null terminator
1115 if (Q_strlen(p
) > j
)
1119 strcat (text
, "\n");
1122 for (j
= 0, client
= svs
.clients
; j
< svs
.maxclients
; j
++, client
++)
1124 if (!client
->active
|| !client
->spawned
)
1126 if (Q_strcasecmp(client
->name
, Cmd_Argv(1)))
1128 host_client
= client
;
1129 SV_ClientPrintf("%s", text
);
1141 void Host_Color_f(void)
1146 if (Cmd_Argc() == 1)
1148 Con_Printf ("\"color\" is \"%i %i\"\n", ((int)cl_color
.value
) >> 4, ((int)cl_color
.value
) & 0x0f);
1149 Con_Printf ("color <0-13> [0-13]\n");
1153 if (Cmd_Argc() == 2)
1154 top
= bottom
= atoi(Cmd_Argv(1));
1157 top
= atoi(Cmd_Argv(1));
1158 bottom
= atoi(Cmd_Argv(2));
1168 playercolor
= top
*16 + bottom
;
1170 if (cmd_source
== src_command
)
1172 Cvar_SetValue ("_cl_color", playercolor
);
1173 if (cls
.state
== ca_connected
)
1174 Cmd_ForwardToServer ();
1178 host_client
->colors
= playercolor
;
1179 host_client
->edict
->v
.team
= bottom
+ 1;
1181 // send notification to all clients
1182 MSG_WriteByte (&sv
.reliable_datagram
, svc_updatecolors
);
1183 MSG_WriteByte (&sv
.reliable_datagram
, host_client
- svs
.clients
);
1184 MSG_WriteByte (&sv
.reliable_datagram
, host_client
->colors
);
1192 void Host_Kill_f (void)
1194 if (cmd_source
== src_command
)
1196 Cmd_ForwardToServer ();
1200 if (sv_player
->v
.health
<= 0)
1202 SV_ClientPrintf ("Can't suicide -- allready dead!\n");
1206 pr_global_struct
->time
= sv
.time
;
1207 pr_global_struct
->self
= EDICT_TO_PROG(sv_player
);
1208 PR_ExecuteProgram (pr_global_struct
->ClientKill
);
1217 void Host_Pause_f (void)
1220 if (cmd_source
== src_command
)
1222 Cmd_ForwardToServer ();
1225 if (!pausable
.value
)
1226 SV_ClientPrintf ("Pause not allowed.\n");
1233 SV_BroadcastPrintf ("%s paused the game\n", pr_strings
+ sv_player
->v
.netname
);
1237 SV_BroadcastPrintf ("%s unpaused the game\n",pr_strings
+ sv_player
->v
.netname
);
1240 // send notification to all clients
1241 MSG_WriteByte (&sv
.reliable_datagram
, svc_setpause
);
1242 MSG_WriteByte (&sv
.reliable_datagram
, sv
.paused
);
1246 //===========================================================================
1254 void Host_PreSpawn_f (void)
1256 if (cmd_source
== src_command
)
1258 Con_Printf ("prespawn is not valid from the console\n");
1262 if (host_client
->spawned
)
1264 Con_Printf ("prespawn not valid -- allready spawned\n");
1268 SZ_Write (&host_client
->message
, sv
.signon
.data
, sv
.signon
.cursize
);
1269 MSG_WriteByte (&host_client
->message
, svc_signonnum
);
1270 MSG_WriteByte (&host_client
->message
, 2);
1271 host_client
->sendsignon
= true;
1279 void Host_Spawn_f (void)
1285 if (cmd_source
== src_command
)
1287 Con_Printf ("spawn is not valid from the console\n");
1291 if (host_client
->spawned
)
1293 Con_Printf ("Spawn not valid -- allready spawned\n");
1297 // run the entrance script
1299 { // loaded games are fully inited allready
1300 // if this is the last client to be connected, unpause
1306 ent
= host_client
->edict
;
1308 memset (&ent
->v
, 0, progs
->entityfields
* 4);
1309 ent
->v
.colormap
= NUM_FOR_EDICT(ent
);
1310 ent
->v
.team
= (host_client
->colors
& 15) + 1;
1311 ent
->v
.netname
= host_client
->name
- pr_strings
;
1313 // copy spawn parms out of the client_t
1315 for (i
=0 ; i
< NUM_SPAWN_PARMS
; i
++)
1316 (&pr_global_struct
->parm1
)[i
] = host_client
->spawn_parms
[i
];
1318 // call the spawn function
1320 pr_global_struct
->time
= sv
.time
;
1321 pr_global_struct
->self
= EDICT_TO_PROG(sv_player
);
1322 PR_ExecuteProgram (pr_global_struct
->ClientConnect
);
1324 if ((Sys_FloatTime() - host_client
->netconnection
->connecttime
) <= sv
.time
)
1325 Sys_Printf ("%s entered the game\n", host_client
->name
);
1327 PR_ExecuteProgram (pr_global_struct
->PutClientInServer
);
1331 // send all current names, colors, and frag counts
1332 SZ_Clear (&host_client
->message
);
1334 // send time of update
1335 MSG_WriteByte (&host_client
->message
, svc_time
);
1336 MSG_WriteFloat (&host_client
->message
, sv
.time
);
1338 for (i
=0, client
= svs
.clients
; i
<svs
.maxclients
; i
++, client
++)
1340 MSG_WriteByte (&host_client
->message
, svc_updatename
);
1341 MSG_WriteByte (&host_client
->message
, i
);
1342 MSG_WriteString (&host_client
->message
, client
->name
);
1343 MSG_WriteByte (&host_client
->message
, svc_updatefrags
);
1344 MSG_WriteByte (&host_client
->message
, i
);
1345 MSG_WriteShort (&host_client
->message
, client
->old_frags
);
1346 MSG_WriteByte (&host_client
->message
, svc_updatecolors
);
1347 MSG_WriteByte (&host_client
->message
, i
);
1348 MSG_WriteByte (&host_client
->message
, client
->colors
);
1351 // send all current light styles
1352 for (i
=0 ; i
<MAX_LIGHTSTYLES
; i
++)
1354 MSG_WriteByte (&host_client
->message
, svc_lightstyle
);
1355 MSG_WriteByte (&host_client
->message
, (char)i
);
1356 MSG_WriteString (&host_client
->message
, sv
.lightstyles
[i
]);
1362 MSG_WriteByte (&host_client
->message
, svc_updatestat
);
1363 MSG_WriteByte (&host_client
->message
, STAT_TOTALSECRETS
);
1364 MSG_WriteLong (&host_client
->message
, pr_global_struct
->total_secrets
);
1366 MSG_WriteByte (&host_client
->message
, svc_updatestat
);
1367 MSG_WriteByte (&host_client
->message
, STAT_TOTALMONSTERS
);
1368 MSG_WriteLong (&host_client
->message
, pr_global_struct
->total_monsters
);
1370 MSG_WriteByte (&host_client
->message
, svc_updatestat
);
1371 MSG_WriteByte (&host_client
->message
, STAT_SECRETS
);
1372 MSG_WriteLong (&host_client
->message
, pr_global_struct
->found_secrets
);
1374 MSG_WriteByte (&host_client
->message
, svc_updatestat
);
1375 MSG_WriteByte (&host_client
->message
, STAT_MONSTERS
);
1376 MSG_WriteLong (&host_client
->message
, pr_global_struct
->killed_monsters
);
1381 // Never send a roll angle, because savegames can catch the server
1382 // in a state where it is expecting the client to correct the angle
1383 // and it won't happen if the game was just loaded, so you wind up
1384 // with a permanent head tilt
1385 ent
= EDICT_NUM( 1 + (host_client
- svs
.clients
) );
1386 MSG_WriteByte (&host_client
->message
, svc_setangle
);
1387 for (i
=0 ; i
< 2 ; i
++)
1388 MSG_WriteAngle (&host_client
->message
, ent
->v
.angles
[i
] );
1389 MSG_WriteAngle (&host_client
->message
, 0 );
1391 SV_WriteClientdataToMessage (sv_player
, &host_client
->message
);
1393 MSG_WriteByte (&host_client
->message
, svc_signonnum
);
1394 MSG_WriteByte (&host_client
->message
, 3);
1395 host_client
->sendsignon
= true;
1403 void Host_Begin_f (void)
1405 if (cmd_source
== src_command
)
1407 Con_Printf ("begin is not valid from the console\n");
1411 host_client
->spawned
= true;
1414 //===========================================================================
1421 Kicks a user off of the server
1424 void Host_Kick_f (void)
1427 char *message
= NULL
;
1430 qboolean byNumber
= false;
1432 if (cmd_source
== src_command
)
1436 Cmd_ForwardToServer ();
1440 else if (pr_global_struct
->deathmatch
&& !host_client
->privileged
)
1445 if (Cmd_Argc() > 2 && Q_strcmp(Cmd_Argv(1), "#") == 0)
1447 i
= Q_atof(Cmd_Argv(2)) - 1;
1448 if (i
< 0 || i
>= svs
.maxclients
)
1450 if (!svs
.clients
[i
].active
)
1452 host_client
= &svs
.clients
[i
];
1457 for (i
= 0, host_client
= svs
.clients
; i
< svs
.maxclients
; i
++, host_client
++)
1459 if (!host_client
->active
)
1461 if (Q_strcasecmp(host_client
->name
, Cmd_Argv(1)) == 0)
1466 if (i
< svs
.maxclients
)
1468 if (cmd_source
== src_command
)
1469 if (cls
.state
== ca_dedicated
)
1472 who
= cl_name
.string
;
1476 // can't kick yourself!
1477 if (host_client
== save
)
1482 message
= COM_Parse(Cmd_Args());
1485 message
++; // skip the #
1486 while (*message
== ' ') // skip white space
1488 message
+= Q_strlen(Cmd_Argv(2)); // skip the number
1490 while (*message
&& *message
== ' ')
1494 SV_ClientPrintf ("Kicked by %s: %s\n", who
, message
);
1496 SV_ClientPrintf ("Kicked by %s\n", who
);
1497 SV_DropClient (false);
1504 ===============================================================================
1508 ===============================================================================
1516 void Host_Give_f (void)
1522 if (cmd_source
== src_command
)
1524 Cmd_ForwardToServer ();
1528 if (pr_global_struct
->deathmatch
&& !host_client
->privileged
)
1532 v
= atoi (Cmd_Argv(2));
1546 // MED 01/04/97 added hipnotic give stuff
1552 sv_player
->v
.items
= (int)sv_player
->v
.items
| HIT_PROXIMITY_GUN
;
1554 sv_player
->v
.items
= (int)sv_player
->v
.items
| IT_GRENADE_LAUNCHER
;
1556 else if (t
[0] == '9')
1557 sv_player
->v
.items
= (int)sv_player
->v
.items
| HIT_LASER_CANNON
;
1558 else if (t
[0] == '0')
1559 sv_player
->v
.items
= (int)sv_player
->v
.items
| HIT_MJOLNIR
;
1560 else if (t
[0] >= '2')
1561 sv_player
->v
.items
= (int)sv_player
->v
.items
| (IT_SHOTGUN
<< (t
[0] - '2'));
1566 sv_player
->v
.items
= (int)sv_player
->v
.items
| (IT_SHOTGUN
<< (t
[0] - '2'));
1573 val
= GetEdictFieldValue(sv_player
, "ammo_shells1");
1578 sv_player
->v
.ammo_shells
= v
;
1583 val
= GetEdictFieldValue(sv_player
, "ammo_nails1");
1587 if (sv_player
->v
.weapon
<= IT_LIGHTNING
)
1588 sv_player
->v
.ammo_nails
= v
;
1593 sv_player
->v
.ammo_nails
= v
;
1599 val
= GetEdictFieldValue(sv_player
, "ammo_lava_nails");
1603 if (sv_player
->v
.weapon
> IT_LIGHTNING
)
1604 sv_player
->v
.ammo_nails
= v
;
1611 val
= GetEdictFieldValue(sv_player
, "ammo_rockets1");
1615 if (sv_player
->v
.weapon
<= IT_LIGHTNING
)
1616 sv_player
->v
.ammo_rockets
= v
;
1621 sv_player
->v
.ammo_rockets
= v
;
1627 val
= GetEdictFieldValue(sv_player
, "ammo_multi_rockets");
1631 if (sv_player
->v
.weapon
> IT_LIGHTNING
)
1632 sv_player
->v
.ammo_rockets
= v
;
1637 sv_player
->v
.health
= v
;
1642 val
= GetEdictFieldValue(sv_player
, "ammo_cells1");
1646 if (sv_player
->v
.weapon
<= IT_LIGHTNING
)
1647 sv_player
->v
.ammo_cells
= v
;
1652 sv_player
->v
.ammo_cells
= v
;
1658 val
= GetEdictFieldValue(sv_player
, "ammo_plasma");
1662 if (sv_player
->v
.weapon
> IT_LIGHTNING
)
1663 sv_player
->v
.ammo_cells
= v
;
1670 edict_t
*FindViewthing (void)
1675 for (i
=0 ; i
<sv
.num_edicts
; i
++)
1678 if ( !strcmp (pr_strings
+ e
->v
.classname
, "viewthing") )
1681 Con_Printf ("No viewthing on map\n");
1690 void Host_Viewmodel_f (void)
1695 e
= FindViewthing ();
1699 m
= Mod_ForName (Cmd_Argv(1), false);
1702 Con_Printf ("Can't load %s\n", Cmd_Argv(1));
1707 cl
.model_precache
[(int)e
->v
.modelindex
] = m
;
1715 void Host_Viewframe_f (void)
1721 e
= FindViewthing ();
1724 m
= cl
.model_precache
[(int)e
->v
.modelindex
];
1726 f
= atoi(Cmd_Argv(1));
1727 if (f
>= m
->numframes
)
1734 void PrintFrameName (model_t
*m
, int frame
)
1737 maliasframedesc_t
*pframedesc
;
1739 hdr
= (aliashdr_t
*)Mod_Extradata (m
);
1742 pframedesc
= &hdr
->frames
[frame
];
1744 Con_Printf ("frame %i: %s\n", frame
, pframedesc
->name
);
1752 void Host_Viewnext_f (void)
1757 e
= FindViewthing ();
1760 m
= cl
.model_precache
[(int)e
->v
.modelindex
];
1762 e
->v
.frame
= e
->v
.frame
+ 1;
1763 if (e
->v
.frame
>= m
->numframes
)
1764 e
->v
.frame
= m
->numframes
- 1;
1766 PrintFrameName (m
, e
->v
.frame
);
1774 void Host_Viewprev_f (void)
1779 e
= FindViewthing ();
1783 m
= cl
.model_precache
[(int)e
->v
.modelindex
];
1785 e
->v
.frame
= e
->v
.frame
- 1;
1789 PrintFrameName (m
, e
->v
.frame
);
1793 ===============================================================================
1797 ===============================================================================
1806 void Host_Startdemos_f (void)
1810 if (cls
.state
== ca_dedicated
)
1813 Cbuf_AddText ("map start\n");
1820 Con_Printf ("Max %i demos in demoloop\n", MAX_DEMOS
);
1823 Con_Printf ("%i demo(s) in loop\n", c
);
1825 for (i
=1 ; i
<c
+1 ; i
++)
1826 strncpy (cls
.demos
[i
-1], Cmd_Argv(i
), sizeof(cls
.demos
[0])-1);
1828 if (!sv
.active
&& cls
.demonum
!= -1 && !cls
.demoplayback
)
1842 Return to looping demos
1845 void Host_Demos_f (void)
1847 if (cls
.state
== ca_dedicated
)
1849 if (cls
.demonum
== -1)
1859 Return to looping demos
1862 void Host_Stopdemo_f (void)
1864 if (cls
.state
== ca_dedicated
)
1866 if (!cls
.demoplayback
)
1872 //=============================================================================
1879 void Host_InitCommands (void)
1881 Cmd_AddCommand ("status", Host_Status_f
);
1882 Cmd_AddCommand ("quit", Host_Quit_f
);
1883 Cmd_AddCommand ("god", Host_God_f
);
1884 Cmd_AddCommand ("notarget", Host_Notarget_f
);
1885 Cmd_AddCommand ("fly", Host_Fly_f
);
1886 Cmd_AddCommand ("map", Host_Map_f
);
1887 Cmd_AddCommand ("restart", Host_Restart_f
);
1888 Cmd_AddCommand ("changelevel", Host_Changelevel_f
);
1890 Cmd_AddCommand ("changelevel2", Host_Changelevel2_f
);
1892 Cmd_AddCommand ("connect", Host_Connect_f
);
1893 Cmd_AddCommand ("reconnect", Host_Reconnect_f
);
1894 Cmd_AddCommand ("name", Host_Name_f
);
1895 Cmd_AddCommand ("noclip", Host_Noclip_f
);
1896 Cmd_AddCommand ("version", Host_Version_f
);
1898 Cmd_AddCommand ("please", Host_Please_f
);
1900 Cmd_AddCommand ("say", Host_Say_f
);
1901 Cmd_AddCommand ("say_team", Host_Say_Team_f
);
1902 Cmd_AddCommand ("tell", Host_Tell_f
);
1903 Cmd_AddCommand ("color", Host_Color_f
);
1904 Cmd_AddCommand ("kill", Host_Kill_f
);
1905 Cmd_AddCommand ("pause", Host_Pause_f
);
1906 Cmd_AddCommand ("spawn", Host_Spawn_f
);
1907 Cmd_AddCommand ("begin", Host_Begin_f
);
1908 Cmd_AddCommand ("prespawn", Host_PreSpawn_f
);
1909 Cmd_AddCommand ("kick", Host_Kick_f
);
1910 Cmd_AddCommand ("ping", Host_Ping_f
);
1911 Cmd_AddCommand ("load", Host_Loadgame_f
);
1912 Cmd_AddCommand ("save", Host_Savegame_f
);
1913 Cmd_AddCommand ("give", Host_Give_f
);
1915 Cmd_AddCommand ("startdemos", Host_Startdemos_f
);
1916 Cmd_AddCommand ("demos", Host_Demos_f
);
1917 Cmd_AddCommand ("stopdemo", Host_Stopdemo_f
);
1919 Cmd_AddCommand ("viewmodel", Host_Viewmodel_f
);
1920 Cmd_AddCommand ("viewframe", Host_Viewframe_f
);
1921 Cmd_AddCommand ("viewnext", Host_Viewnext_f
);
1922 Cmd_AddCommand ("viewprev", Host_Viewprev_f
);
1924 Cmd_AddCommand ("mcache", Mod_Print
);