3 //============================================================================
8 char *vm_sv_extensions =
13 "DP_CON_ALIASPARAMETERS "
31 "DP_ENT_CUSTOMCOLORMAP "
32 "DP_ENT_EXTERIORMODELTOCLIENT "
34 "DP_ENT_LOWPRECISION "
37 "DP_GFX_EXTERNALTEXTURES "
38 "DP_GFX_EXTERNALTEXTURES_PERMAP "
40 "DP_GFX_QUAKE3MODELTAGS "
44 "DP_HALFLIFE_MAP_CVAR "
50 "DP_MOVETYPEBOUNCEMISSILE "
52 "DP_QC_ASINACOSATANATAN2TAN "
55 "DP_QC_CVAR_DEFSTRING "
59 "DP_QC_FINDCHAINFLAGS "
60 "DP_QC_FINDCHAINFLOAT "
68 "DP_QC_MULTIPLETEMPSTRINGS "
70 "DP_QC_SINCOSSQRTPOW "
72 "DP_QC_STRING_CASE_FUNCTIONS "
73 "DP_QC_STRINGBUFFERS "
74 "DP_QC_STRINGCOLORFUNCTIONS "
75 "DP_QC_TOKENIZEBYSEPARATOR "
78 "DP_QC_TRACE_MOVETYPE_HITMODEL "
79 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
80 "DP_QC_UNLIMITEDTEMPSTRINGS "
81 "DP_QC_VECTORVECTORS "
87 "DP_SND_DIRECTIONLESSATTNNONE "
96 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
97 "DP_SV_DRAWONLYTOCLIENT "
100 "DP_SV_ENTITYCONTENTSTRANSITION "
101 "DP_SV_MODELFLAGS_AS_EFFECTS "
103 "DP_SV_NODRAWTOCLIENT "
105 "DP_SV_PLAYERPHYSICS "
106 "DP_SV_POINTPARTICLES "
107 "DP_SV_PRECACHEANYTIME "
110 "DP_SV_ROTATINGBMODEL "
113 "DP_SV_WRITEUNTERMINATEDSTRING "
117 "DP_TE_EXPLOSIONRGB "
119 "DP_TE_PARTICLECUBE "
120 "DP_TE_PARTICLERAIN "
121 "DP_TE_PARTICLESNOW "
123 "DP_TE_QUADEFFECTS1 "
126 "DP_TE_STANDARDEFFECTBUILTINS "
127 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
130 //"EXT_CSQC " // not ready yet
132 "KRIMZON_SV_PARSECLIENTCOMMAND "
135 "NEXUIZ_PLAYERMODEL "
137 "PRYDON_CLIENTCURSOR "
138 "TENEBRAE_GFX_DLIGHTS "
149 This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported.
151 setorigin (entity, origin)
154 static void VM_SV_setorigin (void)
159 VM_SAFEPARMCOUNT(2, VM_setorigin);
161 e = PRVM_G_EDICT(OFS_PARM0);
162 if (e == prog->edicts)
164 VM_Warning("setorigin: can not modify world entity\n");
167 if (e->priv.server->free)
169 VM_Warning("setorigin: can not modify free entity\n");
172 org = PRVM_G_VECTOR(OFS_PARM1);
173 VectorCopy (org, e->fields.server->origin);
174 SV_LinkEdict (e, false);
178 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
182 for (i=0 ; i<3 ; i++)
184 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
186 // set derived values
187 VectorCopy (min, e->fields.server->mins);
188 VectorCopy (max, e->fields.server->maxs);
189 VectorSubtract (max, min, e->fields.server->size);
191 SV_LinkEdict (e, false);
198 the size box is rotated by the current angle
199 LordHavoc: no it isn't...
201 setsize (entity, minvector, maxvector)
204 static void VM_SV_setsize (void)
209 VM_SAFEPARMCOUNT(3, VM_setsize);
211 e = PRVM_G_EDICT(OFS_PARM0);
212 if (e == prog->edicts)
214 VM_Warning("setsize: can not modify world entity\n");
217 if (e->priv.server->free)
219 VM_Warning("setsize: can not modify free entity\n");
222 min = PRVM_G_VECTOR(OFS_PARM1);
223 max = PRVM_G_VECTOR(OFS_PARM2);
224 SetMinMaxSize (e, min, max, false);
232 setmodel(entity, model)
235 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
236 static void VM_SV_setmodel (void)
242 VM_SAFEPARMCOUNT(2, VM_setmodel);
244 e = PRVM_G_EDICT(OFS_PARM0);
245 if (e == prog->edicts)
247 VM_Warning("setmodel: can not modify world entity\n");
250 if (e->priv.server->free)
252 VM_Warning("setmodel: can not modify free entity\n");
255 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
256 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
257 e->fields.server->modelindex = i;
263 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
264 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
266 SetMinMaxSize (e, quakemins, quakemaxs, true);
269 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
276 single print to a specific client
278 sprint(clientent, value)
281 static void VM_SV_sprint (void)
285 char string[VM_STRINGTEMP_LENGTH];
287 VM_VarString(1, string, sizeof(string));
289 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
291 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
292 // LordHavoc: div0 requested that sprintto world operate like print
299 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
301 VM_Warning("tried to centerprint to a non-client\n");
305 client = svs.clients + entnum-1;
306 if (!client->netconnection)
309 MSG_WriteChar(&client->netconnection->message,svc_print);
310 MSG_WriteString(&client->netconnection->message, string);
318 single print to a specific client
320 centerprint(clientent, value)
323 static void VM_SV_centerprint (void)
327 char string[VM_STRINGTEMP_LENGTH];
329 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
331 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
333 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
335 VM_Warning("tried to centerprint to a non-client\n");
339 client = svs.clients + entnum-1;
340 if (!client->netconnection)
343 VM_VarString(1, string, sizeof(string));
344 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
345 MSG_WriteString(&client->netconnection->message, string);
352 particle(origin, color, count)
355 static void VM_SV_particle (void)
361 VM_SAFEPARMCOUNT(4, VM_SV_particle);
363 org = PRVM_G_VECTOR(OFS_PARM0);
364 dir = PRVM_G_VECTOR(OFS_PARM1);
365 color = PRVM_G_FLOAT(OFS_PARM2);
366 count = PRVM_G_FLOAT(OFS_PARM3);
367 SV_StartParticle (org, dir, (int)color, (int)count);
377 static void VM_SV_ambientsound (void)
381 float vol, attenuation;
384 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
386 pos = PRVM_G_VECTOR (OFS_PARM0);
387 samp = PRVM_G_STRING(OFS_PARM1);
388 vol = PRVM_G_FLOAT(OFS_PARM2);
389 attenuation = PRVM_G_FLOAT(OFS_PARM3);
391 // check to see if samp was properly precached
392 soundnum = SV_SoundIndex(samp, 1);
400 // add an svc_spawnambient command to the level signon packet
403 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
405 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
407 MSG_WriteVector(&sv.signon, pos, sv.protocol);
410 MSG_WriteShort (&sv.signon, soundnum);
412 MSG_WriteByte (&sv.signon, soundnum);
414 MSG_WriteByte (&sv.signon, (int)(vol*255));
415 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
423 Each entity can have eight independant sound sources, like voice,
426 Channel 0 is an auto-allocate channel, the others override anything
427 already running on that entity/channel pair.
429 An attenuation of 0 will play full volume everywhere in the level.
430 Larger attenuations will drop off.
434 static void VM_SV_sound (void)
438 prvm_edict_t *entity;
442 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
444 entity = PRVM_G_EDICT(OFS_PARM0);
445 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
446 sample = PRVM_G_STRING(OFS_PARM2);
447 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
448 attenuation = PRVM_G_FLOAT(OFS_PARM4);
451 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
455 if (volume < 0 || volume > 255)
457 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
461 if (attenuation < 0 || attenuation > 4)
463 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
467 if (channel < 0 || channel > 7)
469 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
473 SV_StartSound (entity, channel, sample, volume, attenuation);
480 Used for use tracing and shot targeting
481 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
482 if the tryents flag is set.
484 traceline (vector1, vector2, movetype, ignore)
487 static void VM_SV_traceline (void)
494 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
496 prog->xfunction->builtinsprofile += 30;
498 v1 = PRVM_G_VECTOR(OFS_PARM0);
499 v2 = PRVM_G_VECTOR(OFS_PARM1);
500 move = (int)PRVM_G_FLOAT(OFS_PARM2);
501 ent = PRVM_G_EDICT(OFS_PARM3);
503 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
504 PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
506 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
508 VM_SetTraceGlobals(&trace);
516 Used for use tracing and shot targeting
517 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
518 if the tryents flag is set.
520 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
523 // LordHavoc: added this for my own use, VERY useful, similar to traceline
524 static void VM_SV_tracebox (void)
526 float *v1, *v2, *m1, *m2;
531 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
533 prog->xfunction->builtinsprofile += 30;
535 v1 = PRVM_G_VECTOR(OFS_PARM0);
536 m1 = PRVM_G_VECTOR(OFS_PARM1);
537 m2 = PRVM_G_VECTOR(OFS_PARM2);
538 v2 = PRVM_G_VECTOR(OFS_PARM3);
539 move = (int)PRVM_G_FLOAT(OFS_PARM4);
540 ent = PRVM_G_EDICT(OFS_PARM5);
542 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
543 PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
545 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
547 VM_SetTraceGlobals(&trace);
550 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
555 vec3_t original_origin;
556 vec3_t original_velocity;
557 vec3_t original_angles;
558 vec3_t original_avelocity;
562 VectorCopy(tossent->fields.server->origin , original_origin );
563 VectorCopy(tossent->fields.server->velocity , original_velocity );
564 VectorCopy(tossent->fields.server->angles , original_angles );
565 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
567 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
568 if (val != NULL && val->_float != 0)
569 gravity = val->_float;
572 gravity *= sv_gravity.value * 0.05;
574 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
576 SV_CheckVelocity (tossent);
577 tossent->fields.server->velocity[2] -= gravity;
578 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
579 VectorScale (tossent->fields.server->velocity, 0.05, move);
580 VectorAdd (tossent->fields.server->origin, move, end);
581 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
582 VectorCopy (trace.endpos, tossent->fields.server->origin);
584 if (trace.fraction < 1)
588 VectorCopy(original_origin , tossent->fields.server->origin );
589 VectorCopy(original_velocity , tossent->fields.server->velocity );
590 VectorCopy(original_angles , tossent->fields.server->angles );
591 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
596 static void VM_SV_tracetoss (void)
600 prvm_edict_t *ignore;
602 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
604 prog->xfunction->builtinsprofile += 600;
606 ent = PRVM_G_EDICT(OFS_PARM0);
607 if (ent == prog->edicts)
609 VM_Warning("tracetoss: can not use world entity\n");
612 ignore = PRVM_G_EDICT(OFS_PARM1);
614 trace = SV_Trace_Toss (ent, ignore);
616 VM_SetTraceGlobals(&trace);
619 //============================================================================
621 static int checkpvsbytes;
622 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
624 static int VM_SV_newcheckclient (int check)
630 // cycle to the next one
632 check = bound(1, check, svs.maxclients);
633 if (check == svs.maxclients)
641 prog->xfunction->builtinsprofile++;
643 if (i == svs.maxclients+1)
645 // look up the client's edict
646 ent = PRVM_EDICT_NUM(i);
647 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
648 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
650 // found a valid client (possibly the same one again)
654 // get the PVS for the entity
655 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
657 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
658 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
667 Returns a client (or object that has a client enemy) that would be a
670 If there is more than one valid option, they are cycled each frame
672 If (self.origin + self.viewofs) is not in the PVS of the current target,
673 it is not returned at all.
678 int c_invis, c_notvis;
679 static void VM_SV_checkclient (void)
681 prvm_edict_t *ent, *self;
684 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
686 // find a new check if on a new frame
687 if (sv.time - sv.lastchecktime >= 0.1)
689 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
690 sv.lastchecktime = sv.time;
693 // return check if it might be visible
694 ent = PRVM_EDICT_NUM(sv.lastcheck);
695 if (ent->priv.server->free || ent->fields.server->health <= 0)
697 VM_RETURN_EDICT(prog->edicts);
701 // if current entity can't possibly see the check entity, return 0
702 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
703 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
704 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
707 VM_RETURN_EDICT(prog->edicts);
711 // might be able to see it
713 VM_RETURN_EDICT(ent);
716 //============================================================================
723 Sends text over to the client's execution buffer
725 stuffcmd (clientent, value, ...)
728 static void VM_SV_stuffcmd (void)
732 char string[VM_STRINGTEMP_LENGTH];
734 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
736 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
737 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
739 VM_Warning("Can't stuffcmd to a non-client\n");
743 VM_VarString(1, string, sizeof(string));
746 host_client = svs.clients + entnum-1;
747 Host_ClientCommands ("%s", string);
755 Returns a chain of entities that have origins within a spherical area
757 findradius (origin, radius)
760 static void VM_SV_findradius (void)
762 prvm_edict_t *ent, *chain;
763 vec_t radius, radius2;
764 vec3_t org, eorg, mins, maxs;
767 prvm_edict_t *touchedicts[MAX_EDICTS];
769 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
771 chain = (prvm_edict_t *)prog->edicts;
773 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
774 radius = PRVM_G_FLOAT(OFS_PARM1);
775 radius2 = radius * radius;
777 mins[0] = org[0] - (radius + 1);
778 mins[1] = org[1] - (radius + 1);
779 mins[2] = org[2] - (radius + 1);
780 maxs[0] = org[0] + (radius + 1);
781 maxs[1] = org[1] + (radius + 1);
782 maxs[2] = org[2] + (radius + 1);
783 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
784 if (numtouchedicts > MAX_EDICTS)
786 // this never happens
787 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
788 numtouchedicts = MAX_EDICTS;
790 for (i = 0;i < numtouchedicts;i++)
792 ent = touchedicts[i];
793 prog->xfunction->builtinsprofile++;
794 // Quake did not return non-solid entities but darkplaces does
795 // (note: this is the reason you can't blow up fallen zombies)
796 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
798 // LordHavoc: compare against bounding box rather than center so it
799 // doesn't miss large objects, and use DotProduct instead of Length
800 // for a major speedup
801 VectorSubtract(org, ent->fields.server->origin, eorg);
802 if (sv_gameplayfix_findradiusdistancetobox.integer)
804 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
805 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
806 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
809 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
810 if (DotProduct(eorg, eorg) < radius2)
812 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
817 VM_RETURN_EDICT(chain);
820 static void VM_SV_precache_sound (void)
822 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
823 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
824 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
827 static void VM_SV_precache_model (void)
829 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
830 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
831 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
838 float(float yaw, float dist[, settrace]) walkmove
841 static void VM_SV_walkmove (void)
850 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
852 // assume failure if it returns early
853 PRVM_G_FLOAT(OFS_RETURN) = 0;
855 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
856 if (ent == prog->edicts)
858 VM_Warning("walkmove: can not modify world entity\n");
861 if (ent->priv.server->free)
863 VM_Warning("walkmove: can not modify free entity\n");
866 yaw = PRVM_G_FLOAT(OFS_PARM0);
867 dist = PRVM_G_FLOAT(OFS_PARM1);
868 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
870 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
873 yaw = yaw*M_PI*2 / 360;
875 move[0] = cos(yaw)*dist;
876 move[1] = sin(yaw)*dist;
879 // save program state, because SV_movestep may call other progs
880 oldf = prog->xfunction;
881 oldself = prog->globals.server->self;
883 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
886 // restore program state
887 prog->xfunction = oldf;
888 prog->globals.server->self = oldself;
898 static void VM_SV_droptofloor (void)
904 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
906 // assume failure if it returns early
907 PRVM_G_FLOAT(OFS_RETURN) = 0;
909 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
910 if (ent == prog->edicts)
912 VM_Warning("droptofloor: can not modify world entity\n");
915 if (ent->priv.server->free)
917 VM_Warning("droptofloor: can not modify free entity\n");
921 VectorCopy (ent->fields.server->origin, end);
924 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
926 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
928 if (trace.fraction < 1)
929 VectorCopy (trace.endpos, ent->fields.server->origin);
930 SV_LinkEdict (ent, false);
931 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
932 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
933 PRVM_G_FLOAT(OFS_RETURN) = 1;
934 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
935 ent->priv.server->suspendedinairflag = true;
943 void(float style, string value) lightstyle
946 static void VM_SV_lightstyle (void)
953 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
955 style = (int)PRVM_G_FLOAT(OFS_PARM0);
956 val = PRVM_G_STRING(OFS_PARM1);
958 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
959 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
962 // change the string in sv
963 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
965 // send message to all clients on this server
966 if (sv.state != ss_active)
969 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
971 if (client->active && client->netconnection)
973 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
974 MSG_WriteChar (&client->netconnection->message,style);
975 MSG_WriteString (&client->netconnection->message, val);
985 static void VM_SV_checkbottom (void)
987 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
988 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
996 static void VM_SV_pointcontents (void)
998 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
999 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1006 Pick a vector for the player to shoot along
1007 vector aim(entity, missilespeed)
1010 static void VM_SV_aim (void)
1012 prvm_edict_t *ent, *check, *bestent;
1013 vec3_t start, dir, end, bestdir;
1016 float dist, bestdist;
1019 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1021 // assume failure if it returns early
1022 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1023 // if sv_aim is so high it can't possibly accept anything, skip out early
1024 if (sv_aim.value >= 1)
1027 ent = PRVM_G_EDICT(OFS_PARM0);
1028 if (ent == prog->edicts)
1030 VM_Warning("aim: can not use world entity\n");
1033 if (ent->priv.server->free)
1035 VM_Warning("aim: can not use free entity\n");
1038 speed = PRVM_G_FLOAT(OFS_PARM1);
1040 VectorCopy (ent->fields.server->origin, start);
1043 // try sending a trace straight
1044 VectorCopy (prog->globals.server->v_forward, dir);
1045 VectorMA (start, 2048, dir, end);
1046 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1047 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1048 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1050 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1055 // try all possible entities
1056 VectorCopy (dir, bestdir);
1057 bestdist = sv_aim.value;
1060 check = PRVM_NEXT_EDICT(prog->edicts);
1061 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1063 prog->xfunction->builtinsprofile++;
1064 if (check->fields.server->takedamage != DAMAGE_AIM)
1068 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1069 continue; // don't aim at teammate
1070 for (j=0 ; j<3 ; j++)
1071 end[j] = check->fields.server->origin[j]
1072 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1073 VectorSubtract (end, start, dir);
1074 VectorNormalize (dir);
1075 dist = DotProduct (dir, prog->globals.server->v_forward);
1076 if (dist < bestdist)
1077 continue; // to far to turn
1078 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1079 if (tr.ent == check)
1080 { // can shoot at this one
1088 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1089 dist = DotProduct (dir, prog->globals.server->v_forward);
1090 VectorScale (prog->globals.server->v_forward, dist, end);
1092 VectorNormalize (end);
1093 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1097 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1102 ===============================================================================
1106 ===============================================================================
1109 #define MSG_BROADCAST 0 // unreliable to all
1110 #define MSG_ONE 1 // reliable to one (msg_entity)
1111 #define MSG_ALL 2 // reliable to all
1112 #define MSG_INIT 3 // write to the init string
1113 #define MSG_ENTITY 5
1115 sizebuf_t *WriteDest (void)
1121 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1125 return &sv.datagram;
1128 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1129 entnum = PRVM_NUM_FOR_EDICT(ent);
1130 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1132 VM_Warning ("WriteDest: tried to write to non-client\n");
1133 return &sv.reliable_datagram;
1136 return &svs.clients[entnum-1].netconnection->message;
1139 VM_Warning ("WriteDest: bad destination\n");
1141 return &sv.reliable_datagram;
1147 return sv.writeentitiestoclient_msg;
1153 static void VM_SV_WriteByte (void)
1155 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1156 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1159 static void VM_SV_WriteChar (void)
1161 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1162 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1165 static void VM_SV_WriteShort (void)
1167 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1168 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1171 static void VM_SV_WriteLong (void)
1173 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1174 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1177 static void VM_SV_WriteAngle (void)
1179 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1180 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1183 static void VM_SV_WriteCoord (void)
1185 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1186 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1189 static void VM_SV_WriteString (void)
1191 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1192 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1195 static void VM_SV_WriteUnterminatedString (void)
1197 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1198 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1202 static void VM_SV_WriteEntity (void)
1204 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1205 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1208 //////////////////////////////////////////////////////////
1210 static void VM_SV_makestatic (void)
1215 // allow 0 parameters due to an id1 qc bug in which this function is used
1216 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1217 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1219 if (prog->argc >= 1)
1220 ent = PRVM_G_EDICT(OFS_PARM0);
1222 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1223 if (ent == prog->edicts)
1225 VM_Warning("makestatic: can not modify world entity\n");
1228 if (ent->priv.server->free)
1230 VM_Warning("makestatic: can not modify free entity\n");
1235 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1240 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1241 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1242 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1246 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1247 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1248 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1251 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1252 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1253 for (i=0 ; i<3 ; i++)
1255 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1256 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1259 // throw the entity away now
1263 //=============================================================================
1270 static void VM_SV_setspawnparms (void)
1276 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1278 ent = PRVM_G_EDICT(OFS_PARM0);
1279 i = PRVM_NUM_FOR_EDICT(ent);
1280 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1282 Con_Print("tried to setspawnparms on a non-client\n");
1286 // copy spawn parms out of the client_t
1287 client = svs.clients + i-1;
1288 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1289 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1296 Returns a color vector indicating the lighting at the requested point.
1298 (Internal Operation note: actually measures the light beneath the point, just like
1299 the model lighting on the client)
1304 static void VM_SV_getlight (void)
1306 vec3_t ambientcolor, diffusecolor, diffusenormal;
1308 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1309 p = PRVM_G_VECTOR(OFS_PARM0);
1310 VectorClear(ambientcolor);
1311 VectorClear(diffusecolor);
1312 VectorClear(diffusenormal);
1313 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1314 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1315 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1320 unsigned char type; // 1/2/8 or other value if isn't used
1324 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1325 static int vm_customstats_last;
1327 void VM_CustomStats_Clear (void)
1331 Z_Free(vm_customstats);
1332 vm_customstats = NULL;
1333 vm_customstats_last = -1;
1337 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1345 for(i=0; i<vm_customstats_last+1 ;i++)
1347 if(!vm_customstats[i].type)
1349 switch(vm_customstats[i].type)
1351 //string as 16 bytes
1354 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1355 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1356 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1357 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1358 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1360 //float field sent as-is
1362 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1364 //integer value of float field
1366 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1374 // void(float index, float type, .void field) SV_AddStat = #232;
1375 // Set up an auto-sent player stat.
1376 // Client's get thier own fields sent to them. Index may not be less than 32.
1377 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1378 // 1: string (4 stats carrying a total of 16 charactures)
1379 // 2: float (one stat, float converted to an integer for transportation)
1380 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1381 static void VM_SV_AddStat (void)
1386 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1390 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1393 VM_Warning("PF_SV_AddStat: not enough memory\n");
1397 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1398 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1399 off = PRVM_G_INT (OFS_PARM2);
1404 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1407 if(i >= (MAX_CL_STATS-32))
1409 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1412 if(i > (MAX_CL_STATS-32-4) && type == 1)
1414 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1417 vm_customstats[i].type = type;
1418 vm_customstats[i].fieldoffset = off;
1419 if(vm_customstats_last < i)
1420 vm_customstats_last = i;
1427 copies data from one entity to another
1429 copyentity(src, dst)
1432 static void VM_SV_copyentity (void)
1434 prvm_edict_t *in, *out;
1435 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1436 in = PRVM_G_EDICT(OFS_PARM0);
1437 if (in == prog->edicts)
1439 VM_Warning("copyentity: can not read world entity\n");
1442 if (in->priv.server->free)
1444 VM_Warning("copyentity: can not read free entity\n");
1447 out = PRVM_G_EDICT(OFS_PARM1);
1448 if (out == prog->edicts)
1450 VM_Warning("copyentity: can not modify world entity\n");
1453 if (out->priv.server->free)
1455 VM_Warning("copyentity: can not modify free entity\n");
1458 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1459 SV_LinkEdict(out, false);
1467 sets the color of a client and broadcasts the update to all connected clients
1469 setcolor(clientent, value)
1472 static void VM_SV_setcolor (void)
1478 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1479 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1480 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1482 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1484 Con_Print("tried to setcolor a non-client\n");
1488 client = svs.clients + entnum-1;
1491 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1493 client->edict->fields.server->team = (i & 15) + 1;
1496 if (client->old_colors != client->colors)
1498 client->old_colors = client->colors;
1499 // send notification to all clients
1500 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1501 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1502 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1510 effect(origin, modelname, startframe, framecount, framerate)
1513 static void VM_SV_effect (void)
1517 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1518 s = PRVM_G_STRING(OFS_PARM1);
1521 VM_Warning("effect: no model specified\n");
1525 i = SV_ModelIndex(s, 1);
1528 VM_Warning("effect: model not precached\n");
1532 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1534 VM_Warning("effect: framecount < 1\n");
1538 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1540 VM_Warning("effect: framerate < 1\n");
1544 SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
1547 static void VM_SV_te_blood (void)
1549 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1550 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1552 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1553 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1555 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1556 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1557 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1559 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1560 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1561 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1563 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1564 SV_FlushBroadcastMessages();
1567 static void VM_SV_te_bloodshower (void)
1569 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1570 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1572 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1573 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1575 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1576 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1577 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1579 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1580 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1581 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1583 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1585 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1586 SV_FlushBroadcastMessages();
1589 static void VM_SV_te_explosionrgb (void)
1591 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1592 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1593 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1595 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1596 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1597 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1599 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1600 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1601 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1602 SV_FlushBroadcastMessages();
1605 static void VM_SV_te_particlecube (void)
1607 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1608 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1610 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1611 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1617 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1618 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1619 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1621 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1622 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1623 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1625 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1627 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1628 // gravity true/false
1629 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1631 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1632 SV_FlushBroadcastMessages();
1635 static void VM_SV_te_particlerain (void)
1637 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1638 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1640 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1641 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1643 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1651 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1652 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1653 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1655 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1657 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1658 SV_FlushBroadcastMessages();
1661 static void VM_SV_te_particlesnow (void)
1663 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1664 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1666 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1667 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1677 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1678 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1679 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1681 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1683 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1684 SV_FlushBroadcastMessages();
1687 static void VM_SV_te_spark (void)
1689 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1690 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1692 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1693 MSG_WriteByte(&sv.datagram, TE_SPARK);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1696 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1697 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1699 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1700 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1701 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1703 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1704 SV_FlushBroadcastMessages();
1707 static void VM_SV_te_gunshotquad (void)
1709 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1710 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1711 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1716 SV_FlushBroadcastMessages();
1719 static void VM_SV_te_spikequad (void)
1721 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1722 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1723 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1727 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1728 SV_FlushBroadcastMessages();
1731 static void VM_SV_te_superspikequad (void)
1733 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1734 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1735 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1740 SV_FlushBroadcastMessages();
1743 static void VM_SV_te_explosionquad (void)
1745 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1746 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1747 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1749 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1750 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1751 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1752 SV_FlushBroadcastMessages();
1755 static void VM_SV_te_smallflash (void)
1757 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1758 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1759 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1763 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1764 SV_FlushBroadcastMessages();
1767 static void VM_SV_te_customflash (void)
1769 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1770 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1772 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1773 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1775 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1776 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1777 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1779 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1781 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1783 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1784 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1785 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1786 SV_FlushBroadcastMessages();
1789 static void VM_SV_te_gunshot (void)
1791 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1792 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1793 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1795 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1796 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1797 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1798 SV_FlushBroadcastMessages();
1801 static void VM_SV_te_spike (void)
1803 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1804 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1805 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1810 SV_FlushBroadcastMessages();
1813 static void VM_SV_te_superspike (void)
1815 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1816 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1817 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1822 SV_FlushBroadcastMessages();
1825 static void VM_SV_te_explosion (void)
1827 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1828 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1829 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1834 SV_FlushBroadcastMessages();
1837 static void VM_SV_te_tarexplosion (void)
1839 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1840 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1841 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1845 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1846 SV_FlushBroadcastMessages();
1849 static void VM_SV_te_wizspike (void)
1851 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1852 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1853 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1858 SV_FlushBroadcastMessages();
1861 static void VM_SV_te_knightspike (void)
1863 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1864 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1865 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1870 SV_FlushBroadcastMessages();
1873 static void VM_SV_te_lavasplash (void)
1875 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1876 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1877 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1882 SV_FlushBroadcastMessages();
1885 static void VM_SV_te_teleport (void)
1887 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1888 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1889 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1894 SV_FlushBroadcastMessages();
1897 static void VM_SV_te_explosion2 (void)
1899 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1900 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1901 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1907 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1908 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1909 SV_FlushBroadcastMessages();
1912 static void VM_SV_te_lightning1 (void)
1914 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1915 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1916 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1918 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1927 SV_FlushBroadcastMessages();
1930 static void VM_SV_te_lightning2 (void)
1932 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1933 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1934 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1936 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1945 SV_FlushBroadcastMessages();
1948 static void VM_SV_te_lightning3 (void)
1950 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1951 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1952 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1954 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1963 SV_FlushBroadcastMessages();
1966 static void VM_SV_te_beam (void)
1968 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1969 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1970 MSG_WriteByte(&sv.datagram, TE_BEAM);
1972 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1978 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1981 SV_FlushBroadcastMessages();
1984 static void VM_SV_te_plasmaburn (void)
1986 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1987 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1988 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1992 SV_FlushBroadcastMessages();
1995 static void VM_SV_te_flamejet (void)
1997 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1998 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1999 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2009 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2010 SV_FlushBroadcastMessages();
2013 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2016 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2018 bestdist = 1000000000;
2020 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2022 // clip original point to each triangle of the surface and find the
2023 // triangle that is closest
2024 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2025 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2026 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2027 TriangleNormal(v[0], v[1], v[2], facenormal);
2028 VectorNormalize(facenormal);
2029 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2030 VectorMA(p, offsetdist, facenormal, temp);
2031 for (j = 0, k = 2;j < 3;k = j, j++)
2033 VectorSubtract(v[k], v[j], edgenormal);
2034 CrossProduct(edgenormal, facenormal, sidenormal);
2035 VectorNormalize(sidenormal);
2036 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2038 VectorMA(temp, offsetdist, sidenormal, temp);
2040 dist = VectorDistance2(temp, p);
2041 if (bestdist > dist)
2044 VectorCopy(temp, out);
2049 static model_t *getmodel(prvm_edict_t *ed)
2052 if (!ed || ed->priv.server->free)
2054 modelindex = (int)ed->fields.server->modelindex;
2055 if (modelindex < 1 || modelindex >= MAX_MODELS)
2057 return sv.models[modelindex];
2060 static msurface_t *getsurface(model_t *model, int surfacenum)
2062 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2064 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2068 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2069 static void VM_SV_getsurfacenumpoints(void)
2072 msurface_t *surface;
2073 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2074 // return 0 if no such surface
2075 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2077 PRVM_G_FLOAT(OFS_RETURN) = 0;
2081 // note: this (incorrectly) assumes it is a simple polygon
2082 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2084 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2085 static void VM_SV_getsurfacepoint(void)
2089 msurface_t *surface;
2091 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2092 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2093 ed = PRVM_G_EDICT(OFS_PARM0);
2094 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2096 // note: this (incorrectly) assumes it is a simple polygon
2097 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2098 if (pointnum < 0 || pointnum >= surface->num_vertices)
2100 // FIXME: implement rotation/scaling
2101 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2103 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2104 static void VM_SV_getsurfacenormal(void)
2107 msurface_t *surface;
2109 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2110 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2111 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2113 // FIXME: implement rotation/scaling
2114 // note: this (incorrectly) assumes it is a simple polygon
2115 // note: this only returns the first triangle, so it doesn't work very
2116 // well for curved surfaces or arbitrary meshes
2117 TriangleNormal((model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex), (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 3, (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
2118 VectorNormalize(normal);
2119 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2121 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2122 static void VM_SV_getsurfacetexture(void)
2125 msurface_t *surface;
2126 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2127 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2128 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2130 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2132 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2133 static void VM_SV_getsurfacenearpoint(void)
2135 int surfacenum, best;
2137 vec_t dist, bestdist;
2140 msurface_t *surface;
2142 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2143 PRVM_G_FLOAT(OFS_RETURN) = -1;
2144 ed = PRVM_G_EDICT(OFS_PARM0);
2145 point = PRVM_G_VECTOR(OFS_PARM1);
2147 if (!ed || ed->priv.server->free)
2149 model = getmodel(ed);
2150 if (!model || !model->num_surfaces)
2153 // FIXME: implement rotation/scaling
2154 VectorSubtract(point, ed->fields.server->origin, p);
2156 bestdist = 1000000000;
2157 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2159 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2160 // first see if the nearest point on the surface's box is closer than the previous match
2161 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2162 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2163 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2164 dist = VectorLength2(clipped);
2165 if (dist < bestdist)
2167 // it is, check the nearest point on the actual geometry
2168 clippointtosurface(model, surface, p, clipped);
2169 VectorSubtract(clipped, p, clipped);
2170 dist += VectorLength2(clipped);
2171 if (dist < bestdist)
2173 // that's closer too, store it as the best match
2179 PRVM_G_FLOAT(OFS_RETURN) = best;
2181 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2182 static void VM_SV_getsurfaceclippedpoint(void)
2186 msurface_t *surface;
2188 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2189 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2190 ed = PRVM_G_EDICT(OFS_PARM0);
2191 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2193 // FIXME: implement rotation/scaling
2194 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2195 clippointtosurface(model, surface, p, out);
2196 // FIXME: implement rotation/scaling
2197 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2200 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2201 //this function originally written by KrimZon, made shorter by LordHavoc
2202 static void VM_SV_clientcommand (void)
2204 client_t *temp_client;
2206 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2208 //find client for this entity
2209 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2210 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2212 Con_Print("PF_clientcommand: entity is not a client\n");
2216 temp_client = host_client;
2217 host_client = svs.clients + i;
2218 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2219 host_client = temp_client;
2222 //void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
2223 static void VM_SV_setattachment (void)
2225 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2226 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2227 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2231 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2233 if (e == prog->edicts)
2235 VM_Warning("setattachment: can not modify world entity\n");
2238 if (e->priv.server->free)
2240 VM_Warning("setattachment: can not modify free entity\n");
2244 if (tagentity == NULL)
2245 tagentity = prog->edicts;
2247 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2249 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2251 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2254 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2256 modelindex = (int)tagentity->fields.server->modelindex;
2257 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2259 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2261 Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name);
2264 Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity));
2268 /////////////////////////////////////////
2269 // DP_MD3_TAGINFO extension coded by VorteX
2271 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2276 i = (int)e->fields.server->modelindex;
2277 if (i < 1 || i >= MAX_MODELS)
2279 model = sv.models[i];
2281 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2284 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2286 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2290 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], scale);
2292 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale * cl_viewmodel_scale.value);
2295 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2301 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2302 && (model = sv.models[(int)ent->fields.server->modelindex])
2303 && model->animscenes)
2305 // if model has wrong frame, engine automatically switches to model first frame
2306 frame = (int)ent->fields.server->frame;
2307 if (frame < 0 || frame >= model->numframes)
2309 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2311 *out = identitymatrix;
2315 // Warnings/errors code:
2316 // 0 - normal (everything all-right)
2319 // 3 - null or non-precached model
2320 // 4 - no tags with requested index
2321 // 5 - runaway loop at attachment chain
2322 extern cvar_t cl_bob;
2323 extern cvar_t cl_bobcycle;
2324 extern cvar_t cl_bobup;
2325 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2329 int modelindex, attachloop;
2330 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2333 *out = identitymatrix; // warnings and errors return identical matrix
2335 if (ent == prog->edicts)
2337 if (ent->priv.server->free)
2340 modelindex = (int)ent->fields.server->modelindex;
2341 if (modelindex <= 0 || modelindex > MAX_MODELS)
2344 model = sv.models[modelindex];
2346 tagmatrix = identitymatrix;
2347 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2351 if (attachloop >= 256) // prevent runaway looping
2353 // apply transformation by child's tagindex on parent entity and then
2354 // by parent entity itself
2355 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2356 if (ret && attachloop == 0)
2358 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2359 SV_GetEntityMatrix(ent, &entitymatrix, false);
2360 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2361 // next iteration we process the parent entity
2362 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2364 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2365 ent = PRVM_EDICT_NUM(val->edict);
2372 // RENDER_VIEWMODEL magic
2373 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2375 Matrix4x4_Copy(&tagmatrix, out);
2376 ent = PRVM_EDICT_NUM(val->edict);
2378 SV_GetEntityMatrix(ent, &entitymatrix, true);
2379 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2382 // Cl_bob, ported from rendering code
2383 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2386 // LordHavoc: this code is *weird*, but not replacable (I think it
2387 // should be done in QC on the server, but oh well, quake is quake)
2388 // LordHavoc: figured out bobup: the time at which the sin is at 180
2389 // degrees (which allows lengthening or squishing the peak or valley)
2390 cycle = sv.time/cl_bobcycle.value;
2391 cycle -= (int)cycle;
2392 if (cycle < cl_bobup.value)
2393 cycle = sin(M_PI * cycle / cl_bobup.value);
2395 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2396 // bob is proportional to velocity in the xy plane
2397 // (don't count Z, or jumping messes it up)
2398 bob = sqrt(ent->fields.server->velocity[0]*ent->fields.server->velocity[0] + ent->fields.server->velocity[1]*ent->fields.server->velocity[1])*cl_bob.value;
2399 bob = bob*0.3 + bob*0.7*cycle;
2400 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2407 //float(entity ent, string tagname) gettagindex;
2409 static void VM_SV_gettagindex (void)
2412 const char *tag_name;
2413 int modelindex, tag_index;
2415 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2417 ent = PRVM_G_EDICT(OFS_PARM0);
2418 tag_name = PRVM_G_STRING(OFS_PARM1);
2420 if (ent == prog->edicts)
2422 VM_Warning("gettagindex: can't affect world entity\n");
2425 if (ent->priv.server->free)
2427 VM_Warning("gettagindex: can't affect free entity\n");
2431 modelindex = (int)ent->fields.server->modelindex;
2433 if (modelindex <= 0 || modelindex > MAX_MODELS)
2434 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2437 tag_index = SV_GetTagIndex(ent, tag_name);
2439 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2441 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2444 //vector(entity ent, float tagindex) gettaginfo;
2445 static void VM_SV_gettaginfo (void)
2449 matrix4x4_t tag_matrix;
2452 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2454 e = PRVM_G_EDICT(OFS_PARM0);
2455 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2457 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2458 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2463 VM_Warning("gettagindex: can't affect world entity\n");
2466 VM_Warning("gettagindex: can't affect free entity\n");
2469 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2472 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2475 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2480 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2481 static void VM_SV_dropclient (void)
2484 client_t *oldhostclient;
2485 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2486 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2487 if (clientnum < 0 || clientnum >= svs.maxclients)
2489 VM_Warning("dropclient: not a client\n");
2492 if (!svs.clients[clientnum].active)
2494 VM_Warning("dropclient: that client slot is not connected\n");
2497 oldhostclient = host_client;
2498 host_client = svs.clients + clientnum;
2499 SV_DropClient(false);
2500 host_client = oldhostclient;
2503 //entity() spawnclient (DP_SV_BOTCLIENT)
2504 static void VM_SV_spawnclient (void)
2508 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2509 prog->xfunction->builtinsprofile += 2;
2511 for (i = 0;i < svs.maxclients;i++)
2513 if (!svs.clients[i].active)
2515 prog->xfunction->builtinsprofile += 100;
2516 SV_ConnectClient (i, NULL);
2517 // this has to be set or else ClientDisconnect won't be called
2518 // we assume the qc will call ClientConnect...
2519 svs.clients[i].clientconnectcalled = true;
2520 ed = PRVM_EDICT_NUM(i + 1);
2524 VM_RETURN_EDICT(ed);
2527 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2528 static void VM_SV_clienttype (void)
2531 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2532 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2533 if (clientnum < 0 || clientnum >= svs.maxclients)
2534 PRVM_G_FLOAT(OFS_RETURN) = 3;
2535 else if (!svs.clients[clientnum].active)
2536 PRVM_G_FLOAT(OFS_RETURN) = 0;
2537 else if (svs.clients[clientnum].netconnection)
2538 PRVM_G_FLOAT(OFS_RETURN) = 1;
2540 PRVM_G_FLOAT(OFS_RETURN) = 2;
2547 string(string key) serverkey
2550 void VM_SV_serverkey(void)
2552 char string[VM_STRINGTEMP_LENGTH];
2553 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2554 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2555 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2558 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2559 static void VM_SV_setmodelindex (void)
2564 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2566 e = PRVM_G_EDICT(OFS_PARM0);
2567 if (e == prog->edicts)
2569 VM_Warning("setmodelindex: can not modify world entity\n");
2572 if (e->priv.server->free)
2574 VM_Warning("setmodelindex: can not modify free entity\n");
2577 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2578 if (i <= 0 || i > MAX_MODELS)
2580 VM_Warning("setmodelindex: invalid modelindex\n");
2583 if (!sv.model_precache[i][0])
2585 VM_Warning("setmodelindex: model not precached\n");
2589 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2590 e->fields.server->modelindex = i;
2596 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2597 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2599 SetMinMaxSize (e, quakemins, quakemaxs, true);
2602 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2605 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2606 static void VM_SV_modelnameforindex (void)
2609 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2611 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2613 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2614 if (i <= 0 || i > MAX_MODELS)
2616 VM_Warning("modelnameforindex: invalid modelindex\n");
2619 if (!sv.model_precache[i][0])
2621 VM_Warning("modelnameforindex: model not precached\n");
2625 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2628 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2629 static void VM_SV_particleeffectnum (void)
2632 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2633 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2636 PRVM_G_FLOAT(OFS_RETURN) = i;
2639 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2640 static void VM_SV_trailparticles (void)
2642 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2644 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2645 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2646 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2647 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2648 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2649 SV_FlushBroadcastMessages();
2652 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2653 static void VM_SV_pointparticles (void)
2655 int effectnum, count;
2657 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2658 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2659 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2660 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2661 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2662 if (count == 1 && !VectorLength2(vel))
2665 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2666 MSG_WriteShort(&sv.datagram, effectnum);
2667 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2671 // 1+2+12+12+2=29 bytes
2672 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2673 MSG_WriteShort(&sv.datagram, effectnum);
2674 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2675 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2676 MSG_WriteShort(&sv.datagram, count);
2679 SV_FlushBroadcastMessages();
2682 prvm_builtin_t vm_sv_builtins[] = {
2683 NULL, // #0 NULL function (not callable) (QUAKE)
2684 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2685 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2686 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2687 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2688 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2689 VM_break, // #6 void() break (QUAKE)
2690 VM_random, // #7 float() random (QUAKE)
2691 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2692 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2693 VM_error, // #10 void(string e) error (QUAKE)
2694 VM_objerror, // #11 void(string e) objerror (QUAKE)
2695 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2696 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2697 VM_spawn, // #14 entity() spawn (QUAKE)
2698 VM_remove, // #15 void(entity e) remove (QUAKE)
2699 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2700 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2701 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2702 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2703 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2704 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2705 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2706 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2707 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2708 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2709 VM_ftos, // #26 string(float f) ftos (QUAKE)
2710 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2711 VM_coredump, // #28 void() coredump (QUAKE)
2712 VM_traceon, // #29 void() traceon (QUAKE)
2713 VM_traceoff, // #30 void() traceoff (QUAKE)
2714 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2715 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2716 NULL, // #33 (QUAKE)
2717 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2718 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2719 VM_rint, // #36 float(float v) rint (QUAKE)
2720 VM_floor, // #37 float(float v) floor (QUAKE)
2721 VM_ceil, // #38 float(float v) ceil (QUAKE)
2722 NULL, // #39 (QUAKE)
2723 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2724 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2725 NULL, // #42 (QUAKE)
2726 VM_fabs, // #43 float(float f) fabs (QUAKE)
2727 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2728 VM_cvar, // #45 float(string s) cvar (QUAKE)
2729 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2730 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2731 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2732 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2733 NULL, // #50 (QUAKE)
2734 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2735 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2736 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2737 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2738 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2739 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2740 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2741 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2742 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2743 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2744 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2745 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2746 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2747 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2748 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2749 NULL, // #66 (QUAKE)
2750 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2751 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2752 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2753 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2754 NULL, // #71 (QUAKE)
2755 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2756 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2757 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2758 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2759 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2760 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2761 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2762 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2763 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2764 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2765 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2766 NULL, // #83 (QUAKE)
2767 NULL, // #84 (QUAKE)
2768 NULL, // #85 (QUAKE)
2769 NULL, // #86 (QUAKE)
2770 NULL, // #87 (QUAKE)
2771 NULL, // #88 (QUAKE)
2772 NULL, // #89 (QUAKE)
2773 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2774 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2775 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2776 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2777 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2778 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2779 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2780 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2781 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2782 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2783 // FrikaC and Telejano range #100-#199
2794 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2795 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2796 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2797 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2798 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2799 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2800 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2801 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2802 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2803 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2884 // FTEQW range #200-#299
2903 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2906 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
2907 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2908 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2909 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
2910 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
2911 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
2912 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
2913 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2914 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
2915 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
2917 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2985 // CSQC range #300-#399
2986 NULL, // #300 void() clearscene (EXT_CSQC)
2987 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2988 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2989 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2990 NULL, // #304 void() renderscene (EXT_CSQC)
2991 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2992 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2993 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2994 NULL, // #308 void() R_EndPolygon
2996 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2997 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3001 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3002 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3003 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3004 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3005 NULL, // #319 void(string name) freepic (EXT_CSQC)
3006 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3007 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3008 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3009 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3010 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3011 NULL, // #325 void(void) drawresetcliparea
3016 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3017 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3018 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3019 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3020 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3021 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3022 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3023 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3024 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3025 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3026 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3027 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3028 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3029 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3030 NULL, // #344 vector() getmousepos (EXT_CSQC)
3031 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3032 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3033 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3034 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3035 NULL, // #349 float() isdemo (EXT_CSQC)
3036 VM_isserver, // #350 float() isserver (EXT_CSQC)
3037 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3038 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3039 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3040 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3046 NULL, // #360 float() readbyte (EXT_CSQC)
3047 NULL, // #361 float() readchar (EXT_CSQC)
3048 NULL, // #362 float() readshort (EXT_CSQC)
3049 NULL, // #363 float() readlong (EXT_CSQC)
3050 NULL, // #364 float() readcoord (EXT_CSQC)
3051 NULL, // #365 float() readangle (EXT_CSQC)
3052 NULL, // #366 string() readstring (EXT_CSQC)
3053 NULL, // #367 float() readfloat (EXT_CSQC)
3086 // LordHavoc's range #400-#499
3087 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3088 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3089 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3090 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3091 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3092 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3093 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3094 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3095 VM_SV_te_particlecube, // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
3096 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3097 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3098 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3099 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3100 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3101 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3102 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3103 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3104 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3105 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3106 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3107 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3108 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3109 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3110 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3111 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3112 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3113 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3114 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3115 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3116 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3117 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3118 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3119 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3120 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3121 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3122 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3123 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3124 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3125 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3126 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3127 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3128 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3129 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3130 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3131 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3132 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3133 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3134 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3135 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3136 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3137 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3138 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3139 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3140 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3141 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3142 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3143 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3144 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3146 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3147 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3148 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3149 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3150 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3151 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3152 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3153 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3154 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3155 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3156 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3158 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3159 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3160 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3161 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3162 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3163 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3164 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3165 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3166 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3167 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3168 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3169 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3189 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3191 void VM_SV_Cmd_Init(void)
3196 void VM_SV_Cmd_Reset(void)