cleaned up client qc, menu qc, and server qc VM initialization a bit so they have...
[divverent/darkplaces.git] / mvm_cmds.c
1 #include "prvm_cmds.h"
2
3 //============================================================================
4 // Menu
5
6 char *vm_m_extensions =
7 "BX_WAL_SUPPORT "
8 "DP_CINEMATIC_DPV "
9 "DP_MENU_EXTRESPONSEPACKET "
10 "DP_QC_ASINACOSATANATAN2TAN "
11 "DP_QC_STRFTIME "
12 "DP_QC_STRINGCOLORFUNCTIONS "
13 "DP_QC_UNLIMITEDTEMPSTRINGS";
14
15 /*
16 =========
17 VM_M_precache_file
18
19 string  precache_file(string)
20 =========
21 */
22 void VM_M_precache_file (void)
23 {       // precache_file is only used to copy files with qcc, it does nothing
24         VM_SAFEPARMCOUNT(1,VM_precache_file);
25
26         PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
27 }
28
29 /*
30 =========
31 VM_M_preache_error
32
33 used instead of the other VM_precache_* functions in the builtin list
34 =========
35 */
36
37 void VM_M_precache_error (void)
38 {
39         PRVM_ERROR ("PF_Precache_*: Precache can only be done in spawn functions");
40 }
41
42 /*
43 =========
44 VM_M_precache_sound
45
46 string  precache_sound (string sample)
47 =========
48 */
49 void VM_M_precache_sound (void)
50 {
51         const char      *s;
52
53         VM_SAFEPARMCOUNT(1, VM_precache_sound);
54
55         s = PRVM_G_STRING(OFS_PARM0);
56         PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
57         VM_CheckEmptyString (s);
58
59         if(snd_initialized.integer && !S_PrecacheSound (s,true, true))
60         {
61                 VM_Warning("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
62                 return;
63         }
64 }
65
66 /*
67 =========
68 VM_M_setmousetarget
69
70 setmousetarget(float target)
71 =========
72 */
73 void VM_M_setmousetarget(void)
74 {
75         VM_SAFEPARMCOUNT(1, VM_M_setmousetarget);
76
77         switch((int)PRVM_G_FLOAT(OFS_PARM0))
78         {
79         case 1:
80                 in_client_mouse = false;
81                 break;
82         case 2:
83                 in_client_mouse = true;
84                 break;
85         default:
86                 PRVM_ERROR("VM_M_setmousetarget: wrong destination %f !",PRVM_G_FLOAT(OFS_PARM0));
87         }
88 }
89
90 /*
91 =========
92 VM_M_getmousetarget
93
94 float   getmousetarget
95 =========
96 */
97 void VM_M_getmousetarget(void)
98 {
99         VM_SAFEPARMCOUNT(0,VM_M_getmousetarget);
100
101         if(in_client_mouse)
102                 PRVM_G_FLOAT(OFS_RETURN) = 2;
103         else
104                 PRVM_G_FLOAT(OFS_RETURN) = 1;
105 }
106
107
108
109 /*
110 =========
111 VM_M_setkeydest
112
113 setkeydest(float dest)
114 =========
115 */
116 void VM_M_setkeydest(void)
117 {
118         VM_SAFEPARMCOUNT(1,VM_M_setkeydest);
119
120         switch((int)PRVM_G_FLOAT(OFS_PARM0))
121         {
122         case 0:
123                 // key_game
124                 key_dest = key_game;
125                 break;
126         case 2:
127                 // key_menu
128                 key_dest = key_menu;
129                 break;
130         case 1:
131                 // key_message
132                 // key_dest = key_message
133                 // break;
134         default:
135                 PRVM_ERROR("VM_M_setkeydest: wrong destination %f !", PRVM_G_FLOAT(OFS_PARM0));
136         }
137 }
138
139 /*
140 =========
141 VM_M_getkeydest
142
143 float   getkeydest
144 =========
145 */
146 void VM_M_getkeydest(void)
147 {
148         VM_SAFEPARMCOUNT(0,VM_M_getkeydest);
149
150         // key_game = 0, key_message = 1, key_menu = 2, unknown = 3
151         switch(key_dest)
152         {
153         case key_game:
154                 PRVM_G_FLOAT(OFS_RETURN) = 0;
155                 break;
156         case key_menu:
157                 PRVM_G_FLOAT(OFS_RETURN) = 2;
158                 break;
159         case key_message:
160                 // not supported
161                 // PRVM_G_FLOAT(OFS_RETURN) = 1;
162                 // break;
163         default:
164                 PRVM_G_FLOAT(OFS_RETURN) = 3;
165         }
166 }
167
168 /*
169 =========
170 VM_M_callfunction
171
172         callfunction(...,string function_name)
173 Extension: pass
174 =========
175 */
176 mfunction_t *PRVM_ED_FindFunction (const char *name);
177 void VM_M_callfunction(void)
178 {
179         mfunction_t *func;
180         const char *s;
181
182         if(prog->argc == 0)
183                 PRVM_ERROR("VM_M_callfunction: 1 parameter is required !");
184
185         s = PRVM_G_STRING(OFS_PARM0 + (prog->argc - 1));
186
187         VM_CheckEmptyString(s);
188
189         func = PRVM_ED_FindFunction(s);
190
191         if(!func)
192                 PRVM_ERROR("VM_M_callfunciton: function %s not found !", s);
193         else if (func->first_statement < 0)
194         {
195                 // negative statements are built in functions
196                 int builtinnumber = -func->first_statement;
197                 prog->xfunction->builtinsprofile++;
198                 if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
199                         prog->builtins[builtinnumber]();
200                 else
201                         PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
202         }
203         else if(func - prog->functions > 0)
204         {
205                 prog->argc--;
206                 PRVM_ExecuteProgram(func - prog->functions,"");
207                 prog->argc++;
208         }
209 }
210
211 /*
212 =========
213 VM_M_isfunction
214
215 float   isfunction(string function_name)
216 =========
217 */
218 mfunction_t *PRVM_ED_FindFunction (const char *name);
219 void VM_M_isfunction(void)
220 {
221         mfunction_t *func;
222         const char *s;
223
224         VM_SAFEPARMCOUNT(1, VM_M_isfunction);
225
226         s = PRVM_G_STRING(OFS_PARM0);
227
228         VM_CheckEmptyString(s);
229
230         func = PRVM_ED_FindFunction(s);
231
232         if(!func)
233                 PRVM_G_FLOAT(OFS_RETURN) = false;
234         else
235                 PRVM_G_FLOAT(OFS_RETURN) = true;
236 }
237
238 /*
239 =========
240 VM_M_writetofile
241
242         writetofile(float fhandle, entity ent)
243 =========
244 */
245 void VM_M_writetofile(void)
246 {
247         prvm_edict_t * ent;
248         qfile_t *file;
249
250         VM_SAFEPARMCOUNT(2, VM_M_writetofile);
251
252         file = VM_GetFileHandle( (int)PRVM_G_FLOAT(OFS_PARM0) );
253         if( !file )
254         {
255                 VM_Warning("VM_M_writetofile: invalid or closed file handle\n");
256                 return;
257         }
258
259         ent = PRVM_G_EDICT(OFS_PARM1);
260         if(ent->priv.required->free)
261         {
262                 VM_Warning("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
263                 return;
264         }
265
266         PRVM_ED_Write (file, ent);
267 }
268
269 /*
270 =========
271 VM_M_getresolution
272
273 vector  getresolution(float number)
274 =========
275 */
276 extern unsigned short video_resolutions[][2];
277 void VM_M_getresolution(void)
278 {
279         int nr;
280         VM_SAFEPARMCOUNT(1, VM_getresolution);
281
282         nr = (int)PRVM_G_FLOAT(OFS_PARM0);
283
284
285         PRVM_G_VECTOR(OFS_RETURN)[0] = video_resolutions[nr][0];
286         PRVM_G_VECTOR(OFS_RETURN)[1] = video_resolutions[nr][1];
287         PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
288 }
289
290 /*
291 =========
292 VM_M_findkeysforcommand
293
294 string  findkeysforcommand(string command)
295
296 the returned string is an altstring
297 =========
298 */
299 #define NUMKEYS 5 // TODO: merge the constant in keys.c with this one somewhen
300
301 void M_FindKeysForCommand(const char *command, int *keys);
302 void VM_M_findkeysforcommand(void)
303 {
304         const char *cmd;
305         char ret[VM_STRINGTEMP_LENGTH];
306         int keys[NUMKEYS];
307         int i;
308
309         VM_SAFEPARMCOUNT(1, VM_M_findkeysforcommand);
310
311         cmd = PRVM_G_STRING(OFS_PARM0);
312
313         VM_CheckEmptyString(cmd);
314
315         M_FindKeysForCommand(cmd, keys);
316
317         ret[0] = 0;
318         for(i = 0; i < NUMKEYS; i++)
319                 strlcat(ret, va(" \'%i\'", keys[i]), sizeof(ret));
320
321         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(ret);
322 }
323
324 /*
325 =========
326 VM_M_getserverliststat
327
328 float   getserverliststat(float type)
329 =========
330 */
331 /*
332         type:
333 0       serverlist_viewcount
334 1   serverlist_totalcount
335 2       masterquerycount
336 3       masterreplycount
337 4       serverquerycount
338 5       serverreplycount
339 6       sortfield
340 7       sortdescending
341 */
342 void VM_M_getserverliststat( void )
343 {
344         int type;
345         VM_SAFEPARMCOUNT ( 1, VM_M_getserverliststat );
346
347         PRVM_G_FLOAT( OFS_RETURN ) = 0;
348
349         type = (int)PRVM_G_FLOAT( OFS_PARM0 );
350         switch(type)
351         {
352         case 0:
353                 PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_viewcount;
354                 return;
355         case 1:
356                 PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_cachecount;
357         case 2:
358                 PRVM_G_FLOAT ( OFS_RETURN ) = masterquerycount;
359                 return;
360         case 3:
361                 PRVM_G_FLOAT ( OFS_RETURN ) = masterreplycount;
362                 return;
363         case 4:
364                 PRVM_G_FLOAT ( OFS_RETURN ) = serverquerycount;
365                 return;
366         case 5:
367                 PRVM_G_FLOAT ( OFS_RETURN ) = serverreplycount;
368                 return;
369         case 6:
370                 PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_sortbyfield;
371                 return;
372         case 7:
373                 PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_sortdescending;
374                 return;
375         default:
376                 VM_Warning( "VM_M_getserverliststat: bad type %i!\n", type );
377         }
378 }
379
380 /*
381 ========================
382 VM_M_resetserverlistmasks
383
384 resetserverlistmasks()
385 ========================
386 */
387 void VM_M_resetserverlistmasks( void )
388 {
389         ServerList_ResetMasks();
390 }
391
392
393 /*
394 ========================
395 VM_M_setserverlistmaskstring
396
397 setserverlistmaskstring(float mask, float fld, string str, float op)
398 0-511           and
399 512 - 1024      or
400 ========================
401 */
402 void VM_M_setserverlistmaskstring( void )
403 {
404         const char *str;
405         int masknr;
406         serverlist_mask_t *mask;
407         int field;
408
409         VM_SAFEPARMCOUNT( 4, VM_M_setserverlistmaskstring );
410         str = PRVM_G_STRING( OFS_PARM2 );
411
412         masknr = (int)PRVM_G_FLOAT( OFS_PARM0 );
413         if( masknr >= 0 && masknr <= SERVERLIST_ANDMASKCOUNT )
414                 mask = &serverlist_andmasks[masknr];
415         else if( masknr >= 512 && masknr - 512 <= SERVERLIST_ORMASKCOUNT )
416                 mask = &serverlist_ormasks[masknr - 512 ];
417         else
418         {
419                 VM_Warning( "VM_M_setserverlistmaskstring: invalid mask number %i\n", masknr );
420                 return;
421         }
422
423         field = (int) PRVM_G_FLOAT( OFS_PARM1 );
424
425         switch( field ) {
426                 case SLIF_CNAME:
427                         strlcpy( mask->info.cname, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.cname) );
428                         break;
429                 case SLIF_NAME:
430                         strlcpy( mask->info.name, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.name)  );
431                         break;
432                 case SLIF_MAP:
433                         strlcpy( mask->info.map, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.map)  );
434                         break;
435                 case SLIF_MOD:
436                         strlcpy( mask->info.mod, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.mod)  );
437                         break;
438                 case SLIF_GAME:
439                         strlcpy( mask->info.game, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.game)  );
440                         break;
441                 default:
442                         VM_Warning( "VM_M_setserverlistmaskstring: Bad field number %i passed!\n", field );
443                         return;
444         }
445
446         mask->active = true;
447         mask->tests[field] = (serverlist_maskop_t)((int)PRVM_G_FLOAT( OFS_PARM3 ));
448 }
449
450 /*
451 ========================
452 VM_M_setserverlistmasknumber
453
454 setserverlistmasknumber(float mask, float fld, float num, float op)
455
456 0-511           and
457 512 - 1024      or
458 ========================
459 */
460 void VM_M_setserverlistmasknumber( void )
461 {
462         int number;
463         serverlist_mask_t *mask;
464         int     masknr;
465         int field;
466         VM_SAFEPARMCOUNT( 4, VM_M_setserverlistmasknumber );
467
468         masknr = (int)PRVM_G_FLOAT( OFS_PARM0 );
469         if( masknr >= 0 && masknr <= SERVERLIST_ANDMASKCOUNT )
470                 mask = &serverlist_andmasks[masknr];
471         else if( masknr >= 512 && masknr - 512 <= SERVERLIST_ORMASKCOUNT )
472                 mask = &serverlist_ormasks[masknr - 512 ];
473         else
474         {
475                 VM_Warning( "VM_M_setserverlistmasknumber: invalid mask number %i\n", masknr );
476                 return;
477         }
478
479         number = (int)PRVM_G_FLOAT( OFS_PARM2 );
480         field = (int) PRVM_G_FLOAT( OFS_PARM1 );
481
482         switch( field ) {
483                 case SLIF_MAXPLAYERS:
484                         mask->info.maxplayers = number;
485                         break;
486                 case SLIF_NUMPLAYERS:
487                         mask->info.numplayers = number;
488                         break;
489                 case SLIF_PING:
490                         mask->info.ping = number;
491                         break;
492                 case SLIF_PROTOCOL:
493                         mask->info.protocol = number;
494                         break;
495                 default:
496                         VM_Warning( "VM_M_setserverlistmasknumber: Bad field number %i passed!\n", field );
497                         return;
498         }
499
500         mask->active = true;
501         mask->tests[field] = (serverlist_maskop_t)((int)PRVM_G_FLOAT( OFS_PARM3 ));
502 }
503
504
505 /*
506 ========================
507 VM_M_resortserverlist
508
509 resortserverlist
510 ========================
511 */
512 void VM_M_resortserverlist( void )
513 {
514         ServerList_RebuildViewList();
515 }
516
517 /*
518 =========
519 VM_M_getserverliststring
520
521 string  getserverliststring(float field, float hostnr)
522 =========
523 */
524 void VM_M_getserverliststring(void)
525 {
526         serverlist_entry_t *cache;
527         int hostnr;
528
529         VM_SAFEPARMCOUNT(2, VM_M_getserverliststring);
530
531         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
532
533         hostnr = (int)PRVM_G_FLOAT(OFS_PARM1);
534
535         if(hostnr < 0 || hostnr >= serverlist_viewcount)
536         {
537                 Con_Print("VM_M_getserverliststring: bad hostnr passed!\n");
538                 return;
539         }
540         cache = serverlist_viewlist[hostnr];
541         switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) {
542                 case SLIF_CNAME:
543                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.cname );
544                         break;
545                 case SLIF_NAME:
546                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.name );
547                         break;
548                 case SLIF_GAME:
549                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.game );
550                         break;
551                 case SLIF_MOD:
552                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.mod );
553                         break;
554                 case SLIF_MAP:
555                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.map );
556                         break;
557                 // TODO remove this again
558                 case 1024:
559                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->line1 );
560                         break;
561                 case 1025:
562                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->line2 );
563                         break;
564                 default:
565                         Con_Print("VM_M_getserverliststring: bad field number passed!\n");
566         }
567 }
568
569 /*
570 =========
571 VM_M_getserverlistnumber
572
573 float   getserverlistnumber(float field, float hostnr)
574 =========
575 */
576 void VM_M_getserverlistnumber(void)
577 {
578         serverlist_entry_t *cache;
579         int hostnr;
580
581         VM_SAFEPARMCOUNT(2, VM_M_getserverliststring);
582
583         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
584
585         hostnr = (int)PRVM_G_FLOAT(OFS_PARM1);
586
587         if(hostnr < 0 || hostnr >= serverlist_viewcount)
588         {
589                 Con_Print("VM_M_getserverliststring: bad hostnr passed!\n");
590                 return;
591         }
592         cache = serverlist_viewlist[hostnr];
593         switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) {
594                 case SLIF_MAXPLAYERS:
595                         PRVM_G_FLOAT( OFS_RETURN ) = cache->info.maxplayers;
596                         break;
597                 case SLIF_NUMPLAYERS:
598                         PRVM_G_FLOAT( OFS_RETURN ) = cache->info.numplayers;
599                         break;
600                 case SLIF_PING:
601                         PRVM_G_FLOAT( OFS_RETURN ) = cache->info.ping;
602                         break;
603                 case SLIF_PROTOCOL:
604                         PRVM_G_FLOAT( OFS_RETURN ) = cache->info.protocol;
605                         break;
606                 default:
607                         Con_Print("VM_M_getserverlistnumber: bad field number passed!\n");
608         }
609 }
610
611 /*
612 ========================
613 VM_M_setserverlistsort
614
615 setserverlistsort(float field, float descending)
616 ========================
617 */
618 void VM_M_setserverlistsort( void )
619 {
620         VM_SAFEPARMCOUNT( 2, VM_M_setserverlistsort );
621
622         serverlist_sortbyfield = (serverlist_infofield_t)((int)PRVM_G_FLOAT( OFS_PARM0 ));
623         serverlist_sortdescending = (qboolean) PRVM_G_FLOAT( OFS_PARM1 );
624 }
625
626 /*
627 ========================
628 VM_M_refreshserverlist
629
630 refreshserverlist()
631 ========================
632 */
633 void VM_M_refreshserverlist( void )
634 {
635         VM_SAFEPARMCOUNT( 0, VM_M_refreshserverlist );
636         ServerList_QueryList(true, false);
637 }
638
639 /*
640 ========================
641 VM_M_getserverlistindexforkey
642
643 float getserverlistindexforkey(string key)
644 ========================
645 */
646 void VM_M_getserverlistindexforkey( void )
647 {
648         const char *key;
649         VM_SAFEPARMCOUNT( 1, VM_M_getserverlistindexforkey );
650
651         key = PRVM_G_STRING( OFS_PARM0 );
652         VM_CheckEmptyString( key );
653
654         if( !strcmp( key, "cname" ) )
655                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_CNAME;
656         else if( !strcmp( key, "ping" ) )
657                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_PING;
658         else if( !strcmp( key, "game" ) )
659                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_GAME;
660         else if( !strcmp( key, "mod" ) )
661                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MOD;
662         else if( !strcmp( key, "map" ) )
663                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MAP;
664         else if( !strcmp( key, "name" ) )
665                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_NAME;
666         else if( !strcmp( key, "maxplayers" ) )
667                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MAXPLAYERS;
668         else if( !strcmp( key, "numplayers" ) )
669                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_NUMPLAYERS;
670         else if( !strcmp( key, "protocol" ) )
671                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_PROTOCOL;
672         else
673                 PRVM_G_FLOAT( OFS_RETURN ) = -1;
674 }
675
676 /*
677 ========================
678 VM_M_addwantedserverlistkey
679
680 addwantedserverlistkey(string key)
681 ========================
682 */
683 void VM_M_addwantedserverlistkey( void )
684 {
685         VM_SAFEPARMCOUNT( 1, VM_M_addwantedserverlistkey );
686 }
687
688 /*
689 ===============================================================================
690 MESSAGE WRITING
691
692 used only for client and menu
693 severs uses VM_SV_...
694
695 Write*(* data, float type, float to)
696
697 ===============================================================================
698 */
699
700 #define MSG_BROADCAST   0               // unreliable to all
701 #define MSG_ONE                 1               // reliable to one (msg_entity)
702 #define MSG_ALL                 2               // reliable to all
703 #define MSG_INIT                3               // write to the init string
704
705 sizebuf_t *VM_WriteDest (void)
706 {
707         int             dest;
708         int             destclient;
709
710         if(!sv.active)
711                 PRVM_ERROR("VM_WriteDest: game is not server (%s)", PRVM_NAME);
712
713         dest = (int)PRVM_G_FLOAT(OFS_PARM1);
714         switch (dest)
715         {
716         case MSG_BROADCAST:
717                 return &sv.datagram;
718
719         case MSG_ONE:
720                 destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
721                 if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active || !svs.clients[destclient].netconnection)
722                         PRVM_ERROR("VM_clientcommand: %s: invalid client !", PRVM_NAME);
723
724                 return &svs.clients[destclient].netconnection->message;
725
726         case MSG_ALL:
727                 return &sv.reliable_datagram;
728
729         case MSG_INIT:
730                 return &sv.signon;
731
732         default:
733                 PRVM_ERROR ("WriteDest: bad destination");
734                 break;
735         }
736
737         return NULL;
738 }
739
740 void VM_M_WriteByte (void)
741 {
742         MSG_WriteByte (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
743 }
744
745 void VM_M_WriteChar (void)
746 {
747         MSG_WriteChar (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
748 }
749
750 void VM_M_WriteShort (void)
751 {
752         MSG_WriteShort (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
753 }
754
755 void VM_M_WriteLong (void)
756 {
757         MSG_WriteLong (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
758 }
759
760 void VM_M_WriteAngle (void)
761 {
762         MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
763 }
764
765 void VM_M_WriteCoord (void)
766 {
767         MSG_WriteCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
768 }
769
770 void VM_M_WriteString (void)
771 {
772         MSG_WriteString (VM_WriteDest(), PRVM_G_STRING(OFS_PARM0));
773 }
774
775 void VM_M_WriteEntity (void)
776 {
777         MSG_WriteShort (VM_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
778 }
779
780 //string(void) getextresponse = #624; // returns the next extResponse packet that was sent to this client
781 void VM_M_getextresponse (void)
782 {
783         VM_SAFEPARMCOUNT(0,VM_argv);
784
785         if (net_extresponse_count <= 0)
786                 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
787         else
788         {
789                 int first;
790                 --net_extresponse_count;
791                 first = (net_extresponse_last + NET_EXTRESPONSE_MAX - net_extresponse_count) % NET_EXTRESPONSE_MAX;
792                 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(net_extresponse[first]);
793         }
794 }
795
796 prvm_builtin_t vm_m_builtins[] = {
797         0, // to be consistent with the old vm
798         // common builtings (mostly)
799         VM_checkextension,
800         VM_error,
801         VM_objerror,
802         VM_print,
803         VM_bprint,
804         VM_sprint,
805         VM_centerprint,
806         VM_normalize,
807         VM_vlen,
808         VM_vectoyaw,    // #10
809         VM_vectoangles,
810         VM_random,
811         VM_localcmd,
812         VM_cvar,
813         VM_cvar_set,
814         VM_dprint,
815         VM_ftos,
816         VM_fabs,
817         VM_vtos,
818         VM_etos,                // 20
819         VM_stof,
820         VM_spawn,
821         VM_remove,
822         VM_find,
823         VM_findfloat,
824         VM_findchain,
825         VM_findchainfloat,
826         VM_M_precache_file,
827         VM_M_precache_sound,
828         VM_coredump,    // 30
829         VM_traceon,
830         VM_traceoff,
831         VM_eprint,
832         VM_rint,
833         VM_floor,
834         VM_ceil,
835         VM_nextent,
836         VM_sin,
837         VM_cos,
838         VM_sqrt,                // 40
839         VM_randomvec,
840         VM_registercvar,
841         VM_min,
842         VM_max,
843         VM_bound,
844         VM_pow,
845         VM_copyentity,
846         VM_fopen,
847         VM_fclose,
848         VM_fgets,               // 50
849         VM_fputs,
850         VM_strlen,
851         VM_strcat,
852         VM_substring,
853         VM_stov,
854         VM_strzone,
855         VM_strunzone,
856         VM_tokenize,
857         VM_argv,
858         VM_isserver,    // 60
859         VM_clientcount,
860         VM_clientstate,
861         VM_clcommand,
862         VM_changelevel,
863         VM_localsound,
864         VM_getmousepos,
865         VM_gettime,
866         VM_loadfromdata,
867         VM_loadfromfile,
868         VM_modulo,              // 70
869         VM_cvar_string,
870         VM_crash,
871         VM_stackdump,   // 73
872         VM_search_begin,
873         VM_search_end,
874         VM_search_getsize,
875         VM_search_getfilename, // 77
876         VM_chr,
877         VM_itof,
878         VM_ftoe,                // 80
879         VM_itof,                // isString
880         VM_altstr_count,
881         VM_altstr_prepare,
882         VM_altstr_get,
883         VM_altstr_set,
884         VM_altstr_ins,
885         VM_findflags,
886         VM_findchainflags,
887         VM_cvar_defstring, // 89
888         0, // 90
889         e10,                    // 100
890         e100,                   // 200
891         e100,                   // 300
892         e100,                   // 400
893         // msg functions
894         VM_M_WriteByte,
895         VM_M_WriteChar,
896         VM_M_WriteShort,
897         VM_M_WriteLong,
898         VM_M_WriteAngle,
899         VM_M_WriteCoord,
900         VM_M_WriteString,
901         VM_M_WriteEntity,       // 408
902         0,
903         0,                              // 410
904         e10,                    // 420
905         e10,                    // 430
906         e10,                    // 440
907         e10,                    // 450
908         // draw functions
909         VM_iscachedpic,
910         VM_precache_pic,
911         VM_freepic,
912         VM_drawcharacter,
913         VM_drawstring,
914         VM_drawpic,
915         VM_drawfill,
916         VM_drawsetcliparea,
917         VM_drawresetcliparea,
918         VM_getimagesize,// 460
919         VM_cin_open,
920         VM_cin_close,
921         VM_cin_setstate,
922         VM_cin_getstate,
923         VM_cin_restart, // 465
924         VM_drawline,    // 466
925         0,0,0,0,        // 470
926         VM_asin,                                        // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
927         VM_acos,                                        // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
928         VM_atan,                                        // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
929         VM_atan2,                                       // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
930         VM_tan,                                         // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
931         VM_strlennocol,                         // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
932         VM_strdecolorize,                       // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
933         VM_strftime,                            // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
934         0,                              // 479
935         0,                              // 480
936         e10,                    // 490
937         e10,                    // 500
938         e100,                   // 600
939         // menu functions
940         VM_M_setkeydest,
941         VM_M_getkeydest,
942         VM_M_setmousetarget,
943         VM_M_getmousetarget,
944         VM_M_callfunction,
945         VM_M_writetofile,
946         VM_M_isfunction,
947         VM_M_getresolution,
948         VM_keynumtostring,
949         VM_M_findkeysforcommand,// 610
950         VM_M_getserverliststat,
951         VM_M_getserverliststring,
952         VM_parseentitydata,
953         VM_stringtokeynum,
954         VM_M_resetserverlistmasks,
955         VM_M_setserverlistmaskstring,
956         VM_M_setserverlistmasknumber,
957         VM_M_resortserverlist,
958         VM_M_setserverlistsort,
959         VM_M_refreshserverlist,
960         VM_M_getserverlistnumber,
961         VM_M_getserverlistindexforkey,
962         VM_M_addwantedserverlistkey, // 623
963         VM_M_getextresponse
964 };
965
966 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
967
968 void VM_M_Cmd_Init(void)
969 {
970         VM_Cmd_Init();
971 }
972
973 void VM_M_Cmd_Reset(void)
974 {
975         //VM_Cmd_Init();
976         VM_Cmd_Reset();
977 }