5 //============================================================================
10 char *vm_sv_extensions =
15 "DP_CON_ALIASPARAMETERS "
33 "DP_ENT_CUSTOMCOLORMAP "
34 "DP_ENT_EXTERIORMODELTOCLIENT "
36 "DP_ENT_LOWPRECISION "
39 "DP_GFX_EXTERNALTEXTURES "
40 "DP_GFX_EXTERNALTEXTURES_PERMAP "
42 "DP_GFX_QUAKE3MODELTAGS "
46 "DP_HALFLIFE_MAP_CVAR "
52 "DP_MOVETYPEBOUNCEMISSILE "
54 "DP_QC_ASINACOSATANATAN2TAN "
57 "DP_QC_CVAR_DEFSTRING "
61 "DP_QC_FINDCHAINFLAGS "
62 "DP_QC_FINDCHAINFLOAT "
70 "DP_QC_MULTIPLETEMPSTRINGS "
72 "DP_QC_SINCOSSQRTPOW "
74 "DP_QC_STRING_CASE_FUNCTIONS "
75 "DP_QC_STRINGBUFFERS "
76 "DP_QC_STRINGCOLORFUNCTIONS "
77 "DP_QC_TOKENIZEBYSEPARATOR "
80 "DP_QC_TRACE_MOVETYPE_HITMODEL "
81 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
82 "DP_QC_UNLIMITEDTEMPSTRINGS "
83 "DP_QC_VECTOANGLES_WITH_ROLL "
84 "DP_QC_VECTORVECTORS "
90 "DP_SND_DIRECTIONLESSATTNNONE "
99 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
100 "DP_SV_DRAWONLYTOCLIENT "
103 "DP_SV_ENTITYCONTENTSTRANSITION "
104 "DP_SV_ONENTITYNOSPAWNFUNCTION "
105 "DP_SV_MODELFLAGS_AS_EFFECTS "
107 "DP_SV_NODRAWTOCLIENT "
109 "DP_SV_PLAYERPHYSICS "
110 "DP_SV_POINTPARTICLES "
112 "DP_SV_PRECACHEANYTIME "
115 "DP_SV_ROTATINGBMODEL "
118 "DP_SV_WRITEUNTERMINATEDSTRING "
122 "DP_TE_EXPLOSIONRGB "
124 "DP_TE_PARTICLECUBE "
125 "DP_TE_PARTICLERAIN "
126 "DP_TE_PARTICLESNOW "
128 "DP_TE_QUADEFFECTS1 "
131 "DP_TE_STANDARDEFFECTBUILTINS "
132 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
135 //"EXT_CSQC " // not ready yet
137 "KRIMZON_SV_PARSECLIENTCOMMAND "
140 "NEXUIZ_PLAYERMODEL "
142 "PRYDON_CLIENTCURSOR "
143 "TENEBRAE_GFX_DLIGHTS "
156 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.
158 setorigin (entity, origin)
161 static void VM_SV_setorigin (void)
166 VM_SAFEPARMCOUNT(2, VM_setorigin);
168 e = PRVM_G_EDICT(OFS_PARM0);
169 if (e == prog->edicts)
171 VM_Warning("setorigin: can not modify world entity\n");
174 if (e->priv.server->free)
176 VM_Warning("setorigin: can not modify free entity\n");
179 org = PRVM_G_VECTOR(OFS_PARM1);
180 VectorCopy (org, e->fields.server->origin);
181 SV_LinkEdict (e, false);
185 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
189 for (i=0 ; i<3 ; i++)
191 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
193 // set derived values
194 VectorCopy (min, e->fields.server->mins);
195 VectorCopy (max, e->fields.server->maxs);
196 VectorSubtract (max, min, e->fields.server->size);
198 SV_LinkEdict (e, false);
205 the size box is rotated by the current angle
206 LordHavoc: no it isn't...
208 setsize (entity, minvector, maxvector)
211 static void VM_SV_setsize (void)
216 VM_SAFEPARMCOUNT(3, VM_setsize);
218 e = PRVM_G_EDICT(OFS_PARM0);
219 if (e == prog->edicts)
221 VM_Warning("setsize: can not modify world entity\n");
224 if (e->priv.server->free)
226 VM_Warning("setsize: can not modify free entity\n");
229 min = PRVM_G_VECTOR(OFS_PARM1);
230 max = PRVM_G_VECTOR(OFS_PARM2);
231 SetMinMaxSize (e, min, max, false);
239 setmodel(entity, model)
242 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
243 static void VM_SV_setmodel (void)
249 VM_SAFEPARMCOUNT(2, VM_setmodel);
251 e = PRVM_G_EDICT(OFS_PARM0);
252 if (e == prog->edicts)
254 VM_Warning("setmodel: can not modify world entity\n");
257 if (e->priv.server->free)
259 VM_Warning("setmodel: can not modify free entity\n");
262 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
263 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
264 e->fields.server->modelindex = i;
270 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
271 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
273 SetMinMaxSize (e, quakemins, quakemaxs, true);
276 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
283 single print to a specific client
285 sprint(clientent, value)
288 static void VM_SV_sprint (void)
292 char string[VM_STRINGTEMP_LENGTH];
294 VM_VarString(1, string, sizeof(string));
296 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
298 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
299 // LordHavoc: div0 requested that sprintto world operate like print
306 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
308 VM_Warning("tried to centerprint to a non-client\n");
312 client = svs.clients + entnum-1;
313 if (!client->netconnection)
316 MSG_WriteChar(&client->netconnection->message,svc_print);
317 MSG_WriteString(&client->netconnection->message, string);
325 single print to a specific client
327 centerprint(clientent, value)
330 static void VM_SV_centerprint (void)
334 char string[VM_STRINGTEMP_LENGTH];
336 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
338 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
340 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
342 VM_Warning("tried to centerprint to a non-client\n");
346 client = svs.clients + entnum-1;
347 if (!client->netconnection)
350 VM_VarString(1, string, sizeof(string));
351 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
352 MSG_WriteString(&client->netconnection->message, string);
359 particle(origin, color, count)
362 static void VM_SV_particle (void)
368 VM_SAFEPARMCOUNT(4, VM_SV_particle);
370 org = PRVM_G_VECTOR(OFS_PARM0);
371 dir = PRVM_G_VECTOR(OFS_PARM1);
372 color = PRVM_G_FLOAT(OFS_PARM2);
373 count = PRVM_G_FLOAT(OFS_PARM3);
374 SV_StartParticle (org, dir, (int)color, (int)count);
384 static void VM_SV_ambientsound (void)
388 float vol, attenuation;
391 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
393 pos = PRVM_G_VECTOR (OFS_PARM0);
394 samp = PRVM_G_STRING(OFS_PARM1);
395 vol = PRVM_G_FLOAT(OFS_PARM2);
396 attenuation = PRVM_G_FLOAT(OFS_PARM3);
398 // check to see if samp was properly precached
399 soundnum = SV_SoundIndex(samp, 1);
407 // add an svc_spawnambient command to the level signon packet
410 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
412 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
414 MSG_WriteVector(&sv.signon, pos, sv.protocol);
416 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
417 MSG_WriteShort (&sv.signon, soundnum);
419 MSG_WriteByte (&sv.signon, soundnum);
421 MSG_WriteByte (&sv.signon, (int)(vol*255));
422 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
430 Each entity can have eight independant sound sources, like voice,
433 Channel 0 is an auto-allocate channel, the others override anything
434 already running on that entity/channel pair.
436 An attenuation of 0 will play full volume everywhere in the level.
437 Larger attenuations will drop off.
441 static void VM_SV_sound (void)
445 prvm_edict_t *entity;
449 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
451 entity = PRVM_G_EDICT(OFS_PARM0);
452 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
453 sample = PRVM_G_STRING(OFS_PARM2);
454 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
455 attenuation = PRVM_G_FLOAT(OFS_PARM4);
458 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
462 if (volume < 0 || volume > 255)
464 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
468 if (attenuation < 0 || attenuation > 4)
470 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
474 if (channel < 0 || channel > 7)
476 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
480 SV_StartSound (entity, channel, sample, volume, attenuation);
487 Follows the same logic as VM_SV_sound, except instead of
488 an entity, an origin for the sound is provided, and channel
489 is omitted (since no entity is being tracked).
493 static void VM_SV_pointsound(void)
500 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
502 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
503 sample = PRVM_G_STRING(OFS_PARM1);
504 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
505 attenuation = PRVM_G_FLOAT(OFS_PARM3);
507 if (volume < 0 || volume > 255)
509 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
513 if (attenuation < 0 || attenuation > 4)
515 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
519 SV_StartPointSound (org, sample, volume, attenuation);
526 Used for use tracing and shot targeting
527 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
528 if the tryents flag is set.
530 traceline (vector1, vector2, movetype, ignore)
533 static void VM_SV_traceline (void)
540 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
542 prog->xfunction->builtinsprofile += 30;
544 v1 = PRVM_G_VECTOR(OFS_PARM0);
545 v2 = PRVM_G_VECTOR(OFS_PARM1);
546 move = (int)PRVM_G_FLOAT(OFS_PARM2);
547 ent = PRVM_G_EDICT(OFS_PARM3);
549 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]))
550 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));
552 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
554 VM_SetTraceGlobals(&trace);
562 Used for use tracing and shot targeting
563 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
564 if the tryents flag is set.
566 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
569 // LordHavoc: added this for my own use, VERY useful, similar to traceline
570 static void VM_SV_tracebox (void)
572 float *v1, *v2, *m1, *m2;
577 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
579 prog->xfunction->builtinsprofile += 30;
581 v1 = PRVM_G_VECTOR(OFS_PARM0);
582 m1 = PRVM_G_VECTOR(OFS_PARM1);
583 m2 = PRVM_G_VECTOR(OFS_PARM2);
584 v2 = PRVM_G_VECTOR(OFS_PARM3);
585 move = (int)PRVM_G_FLOAT(OFS_PARM4);
586 ent = PRVM_G_EDICT(OFS_PARM5);
588 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]))
589 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));
591 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
593 VM_SetTraceGlobals(&trace);
596 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
601 vec3_t original_origin;
602 vec3_t original_velocity;
603 vec3_t original_angles;
604 vec3_t original_avelocity;
608 VectorCopy(tossent->fields.server->origin , original_origin );
609 VectorCopy(tossent->fields.server->velocity , original_velocity );
610 VectorCopy(tossent->fields.server->angles , original_angles );
611 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
613 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
614 if (val != NULL && val->_float != 0)
615 gravity = val->_float;
618 gravity *= sv_gravity.value * 0.05;
620 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
622 SV_CheckVelocity (tossent);
623 tossent->fields.server->velocity[2] -= gravity;
624 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
625 VectorScale (tossent->fields.server->velocity, 0.05, move);
626 VectorAdd (tossent->fields.server->origin, move, end);
627 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
628 VectorCopy (trace.endpos, tossent->fields.server->origin);
630 if (trace.fraction < 1)
634 VectorCopy(original_origin , tossent->fields.server->origin );
635 VectorCopy(original_velocity , tossent->fields.server->velocity );
636 VectorCopy(original_angles , tossent->fields.server->angles );
637 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
642 static void VM_SV_tracetoss (void)
646 prvm_edict_t *ignore;
648 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
650 prog->xfunction->builtinsprofile += 600;
652 ent = PRVM_G_EDICT(OFS_PARM0);
653 if (ent == prog->edicts)
655 VM_Warning("tracetoss: can not use world entity\n");
658 ignore = PRVM_G_EDICT(OFS_PARM1);
660 trace = SV_Trace_Toss (ent, ignore);
662 VM_SetTraceGlobals(&trace);
665 //============================================================================
667 static int checkpvsbytes;
668 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
670 static int VM_SV_newcheckclient (int check)
676 // cycle to the next one
678 check = bound(1, check, svs.maxclients);
679 if (check == svs.maxclients)
687 prog->xfunction->builtinsprofile++;
689 if (i == svs.maxclients+1)
691 // look up the client's edict
692 ent = PRVM_EDICT_NUM(i);
693 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
694 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
696 // found a valid client (possibly the same one again)
700 // get the PVS for the entity
701 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
703 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
704 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
713 Returns a client (or object that has a client enemy) that would be a
716 If there is more than one valid option, they are cycled each frame
718 If (self.origin + self.viewofs) is not in the PVS of the current target,
719 it is not returned at all.
724 int c_invis, c_notvis;
725 static void VM_SV_checkclient (void)
727 prvm_edict_t *ent, *self;
730 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
732 // find a new check if on a new frame
733 if (sv.time - sv.lastchecktime >= 0.1)
735 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
736 sv.lastchecktime = sv.time;
739 // return check if it might be visible
740 ent = PRVM_EDICT_NUM(sv.lastcheck);
741 if (ent->priv.server->free || ent->fields.server->health <= 0)
743 VM_RETURN_EDICT(prog->edicts);
747 // if current entity can't possibly see the check entity, return 0
748 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
749 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
750 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
753 VM_RETURN_EDICT(prog->edicts);
757 // might be able to see it
759 VM_RETURN_EDICT(ent);
762 //============================================================================
769 Sends text over to the client's execution buffer
771 stuffcmd (clientent, value, ...)
774 static void VM_SV_stuffcmd (void)
778 char string[VM_STRINGTEMP_LENGTH];
780 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
782 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
783 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
785 VM_Warning("Can't stuffcmd to a non-client\n");
789 VM_VarString(1, string, sizeof(string));
792 host_client = svs.clients + entnum-1;
793 Host_ClientCommands ("%s", string);
801 Returns a chain of entities that have origins within a spherical area
803 findradius (origin, radius)
806 static void VM_SV_findradius (void)
808 prvm_edict_t *ent, *chain;
809 vec_t radius, radius2;
810 vec3_t org, eorg, mins, maxs;
813 prvm_edict_t *touchedicts[MAX_EDICTS];
815 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
817 chain = (prvm_edict_t *)prog->edicts;
819 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
820 radius = PRVM_G_FLOAT(OFS_PARM1);
821 radius2 = radius * radius;
823 mins[0] = org[0] - (radius + 1);
824 mins[1] = org[1] - (radius + 1);
825 mins[2] = org[2] - (radius + 1);
826 maxs[0] = org[0] + (radius + 1);
827 maxs[1] = org[1] + (radius + 1);
828 maxs[2] = org[2] + (radius + 1);
829 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
830 if (numtouchedicts > MAX_EDICTS)
832 // this never happens
833 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
834 numtouchedicts = MAX_EDICTS;
836 for (i = 0;i < numtouchedicts;i++)
838 ent = touchedicts[i];
839 prog->xfunction->builtinsprofile++;
840 // Quake did not return non-solid entities but darkplaces does
841 // (note: this is the reason you can't blow up fallen zombies)
842 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
844 // LordHavoc: compare against bounding box rather than center so it
845 // doesn't miss large objects, and use DotProduct instead of Length
846 // for a major speedup
847 VectorSubtract(org, ent->fields.server->origin, eorg);
848 if (sv_gameplayfix_findradiusdistancetobox.integer)
850 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
851 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
852 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
855 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
856 if (DotProduct(eorg, eorg) < radius2)
858 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
863 VM_RETURN_EDICT(chain);
866 static void VM_SV_precache_sound (void)
868 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
869 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
870 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
873 static void VM_SV_precache_model (void)
875 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
876 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
877 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
884 float(float yaw, float dist[, settrace]) walkmove
887 static void VM_SV_walkmove (void)
896 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
898 // assume failure if it returns early
899 PRVM_G_FLOAT(OFS_RETURN) = 0;
901 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
902 if (ent == prog->edicts)
904 VM_Warning("walkmove: can not modify world entity\n");
907 if (ent->priv.server->free)
909 VM_Warning("walkmove: can not modify free entity\n");
912 yaw = PRVM_G_FLOAT(OFS_PARM0);
913 dist = PRVM_G_FLOAT(OFS_PARM1);
914 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
916 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
919 yaw = yaw*M_PI*2 / 360;
921 move[0] = cos(yaw)*dist;
922 move[1] = sin(yaw)*dist;
925 // save program state, because SV_movestep may call other progs
926 oldf = prog->xfunction;
927 oldself = prog->globals.server->self;
929 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
932 // restore program state
933 prog->xfunction = oldf;
934 prog->globals.server->self = oldself;
944 static void VM_SV_droptofloor (void)
950 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
952 // assume failure if it returns early
953 PRVM_G_FLOAT(OFS_RETURN) = 0;
955 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
956 if (ent == prog->edicts)
958 VM_Warning("droptofloor: can not modify world entity\n");
961 if (ent->priv.server->free)
963 VM_Warning("droptofloor: can not modify free entity\n");
967 VectorCopy (ent->fields.server->origin, end);
970 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
972 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
974 if (trace.fraction < 1)
975 VectorCopy (trace.endpos, ent->fields.server->origin);
976 SV_LinkEdict (ent, false);
977 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
978 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
979 PRVM_G_FLOAT(OFS_RETURN) = 1;
980 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
981 ent->priv.server->suspendedinairflag = true;
989 void(float style, string value) lightstyle
992 static void VM_SV_lightstyle (void)
999 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1001 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1002 val = PRVM_G_STRING(OFS_PARM1);
1004 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1005 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1008 // change the string in sv
1009 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1011 // send message to all clients on this server
1012 if (sv.state != ss_active)
1015 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1017 if (client->active && client->netconnection)
1019 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1020 MSG_WriteChar (&client->netconnection->message,style);
1021 MSG_WriteString (&client->netconnection->message, val);
1031 static void VM_SV_checkbottom (void)
1033 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1034 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1042 static void VM_SV_pointcontents (void)
1044 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1045 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1052 Pick a vector for the player to shoot along
1053 vector aim(entity, missilespeed)
1056 static void VM_SV_aim (void)
1058 prvm_edict_t *ent, *check, *bestent;
1059 vec3_t start, dir, end, bestdir;
1062 float dist, bestdist;
1065 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1067 // assume failure if it returns early
1068 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1069 // if sv_aim is so high it can't possibly accept anything, skip out early
1070 if (sv_aim.value >= 1)
1073 ent = PRVM_G_EDICT(OFS_PARM0);
1074 if (ent == prog->edicts)
1076 VM_Warning("aim: can not use world entity\n");
1079 if (ent->priv.server->free)
1081 VM_Warning("aim: can not use free entity\n");
1084 speed = PRVM_G_FLOAT(OFS_PARM1);
1086 VectorCopy (ent->fields.server->origin, start);
1089 // try sending a trace straight
1090 VectorCopy (prog->globals.server->v_forward, dir);
1091 VectorMA (start, 2048, dir, end);
1092 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1093 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1094 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1096 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1101 // try all possible entities
1102 VectorCopy (dir, bestdir);
1103 bestdist = sv_aim.value;
1106 check = PRVM_NEXT_EDICT(prog->edicts);
1107 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1109 prog->xfunction->builtinsprofile++;
1110 if (check->fields.server->takedamage != DAMAGE_AIM)
1114 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1115 continue; // don't aim at teammate
1116 for (j=0 ; j<3 ; j++)
1117 end[j] = check->fields.server->origin[j]
1118 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1119 VectorSubtract (end, start, dir);
1120 VectorNormalize (dir);
1121 dist = DotProduct (dir, prog->globals.server->v_forward);
1122 if (dist < bestdist)
1123 continue; // to far to turn
1124 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1125 if (tr.ent == check)
1126 { // can shoot at this one
1134 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1135 dist = DotProduct (dir, prog->globals.server->v_forward);
1136 VectorScale (prog->globals.server->v_forward, dist, end);
1138 VectorNormalize (end);
1139 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1143 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1148 ===============================================================================
1152 ===============================================================================
1155 #define MSG_BROADCAST 0 // unreliable to all
1156 #define MSG_ONE 1 // reliable to one (msg_entity)
1157 #define MSG_ALL 2 // reliable to all
1158 #define MSG_INIT 3 // write to the init string
1159 #define MSG_ENTITY 5
1161 sizebuf_t *WriteDest (void)
1167 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1171 return &sv.datagram;
1174 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1175 entnum = PRVM_NUM_FOR_EDICT(ent);
1176 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1178 VM_Warning ("WriteDest: tried to write to non-client\n");
1179 return &sv.reliable_datagram;
1182 return &svs.clients[entnum-1].netconnection->message;
1185 VM_Warning ("WriteDest: bad destination\n");
1187 return &sv.reliable_datagram;
1193 return sv.writeentitiestoclient_msg;
1199 static void VM_SV_WriteByte (void)
1201 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1202 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1205 static void VM_SV_WriteChar (void)
1207 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1208 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1211 static void VM_SV_WriteShort (void)
1213 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1214 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1217 static void VM_SV_WriteLong (void)
1219 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1220 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1223 static void VM_SV_WriteAngle (void)
1225 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1226 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1229 static void VM_SV_WriteCoord (void)
1231 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1232 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1235 static void VM_SV_WriteString (void)
1237 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1238 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1241 static void VM_SV_WriteUnterminatedString (void)
1243 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1244 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1248 static void VM_SV_WriteEntity (void)
1250 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1251 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1254 //////////////////////////////////////////////////////////
1256 static void VM_SV_makestatic (void)
1261 // allow 0 parameters due to an id1 qc bug in which this function is used
1262 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1263 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1265 if (prog->argc >= 1)
1266 ent = PRVM_G_EDICT(OFS_PARM0);
1268 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1269 if (ent == prog->edicts)
1271 VM_Warning("makestatic: can not modify world entity\n");
1274 if (ent->priv.server->free)
1276 VM_Warning("makestatic: can not modify free entity\n");
1281 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1286 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1287 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1288 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1290 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1292 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1293 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1294 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1298 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1299 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1300 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1303 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1304 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1305 for (i=0 ; i<3 ; i++)
1307 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1308 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1311 // throw the entity away now
1315 //=============================================================================
1322 static void VM_SV_setspawnparms (void)
1328 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1330 ent = PRVM_G_EDICT(OFS_PARM0);
1331 i = PRVM_NUM_FOR_EDICT(ent);
1332 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1334 Con_Print("tried to setspawnparms on a non-client\n");
1338 // copy spawn parms out of the client_t
1339 client = svs.clients + i-1;
1340 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1341 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1348 Returns a color vector indicating the lighting at the requested point.
1350 (Internal Operation note: actually measures the light beneath the point, just like
1351 the model lighting on the client)
1356 static void VM_SV_getlight (void)
1358 vec3_t ambientcolor, diffusecolor, diffusenormal;
1360 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1361 p = PRVM_G_VECTOR(OFS_PARM0);
1362 VectorClear(ambientcolor);
1363 VectorClear(diffusecolor);
1364 VectorClear(diffusenormal);
1365 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1366 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1367 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1372 unsigned char type; // 1/2/8 or other value if isn't used
1376 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1377 static int vm_customstats_last;
1379 void VM_CustomStats_Clear (void)
1383 Z_Free(vm_customstats);
1384 vm_customstats = NULL;
1385 vm_customstats_last = -1;
1389 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1397 for(i=0; i<vm_customstats_last+1 ;i++)
1399 if(!vm_customstats[i].type)
1401 switch(vm_customstats[i].type)
1403 //string as 16 bytes
1406 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1407 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1408 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1409 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1410 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1412 //float field sent as-is
1414 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1416 //integer value of float field
1418 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1426 // void(float index, float type, .void field) SV_AddStat = #232;
1427 // Set up an auto-sent player stat.
1428 // Client's get thier own fields sent to them. Index may not be less than 32.
1429 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1430 // 1: string (4 stats carrying a total of 16 charactures)
1431 // 2: float (one stat, float converted to an integer for transportation)
1432 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1433 static void VM_SV_AddStat (void)
1438 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1442 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1445 VM_Warning("PF_SV_AddStat: not enough memory\n");
1449 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1450 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1451 off = PRVM_G_INT (OFS_PARM2);
1456 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1459 if(i >= (MAX_CL_STATS-32))
1461 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1464 if(i > (MAX_CL_STATS-32-4) && type == 1)
1466 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1469 vm_customstats[i].type = type;
1470 vm_customstats[i].fieldoffset = off;
1471 if(vm_customstats_last < i)
1472 vm_customstats_last = i;
1479 copies data from one entity to another
1481 copyentity(src, dst)
1484 static void VM_SV_copyentity (void)
1486 prvm_edict_t *in, *out;
1487 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1488 in = PRVM_G_EDICT(OFS_PARM0);
1489 if (in == prog->edicts)
1491 VM_Warning("copyentity: can not read world entity\n");
1494 if (in->priv.server->free)
1496 VM_Warning("copyentity: can not read free entity\n");
1499 out = PRVM_G_EDICT(OFS_PARM1);
1500 if (out == prog->edicts)
1502 VM_Warning("copyentity: can not modify world entity\n");
1505 if (out->priv.server->free)
1507 VM_Warning("copyentity: can not modify free entity\n");
1510 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1511 SV_LinkEdict(out, false);
1519 sets the color of a client and broadcasts the update to all connected clients
1521 setcolor(clientent, value)
1524 static void VM_SV_setcolor (void)
1530 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1531 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1532 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1534 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1536 Con_Print("tried to setcolor a non-client\n");
1540 client = svs.clients + entnum-1;
1543 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1545 client->edict->fields.server->team = (i & 15) + 1;
1548 if (client->old_colors != client->colors)
1550 client->old_colors = client->colors;
1551 // send notification to all clients
1552 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1553 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1554 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1562 effect(origin, modelname, startframe, framecount, framerate)
1565 static void VM_SV_effect (void)
1569 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1570 s = PRVM_G_STRING(OFS_PARM1);
1573 VM_Warning("effect: no model specified\n");
1577 i = SV_ModelIndex(s, 1);
1580 VM_Warning("effect: model not precached\n");
1584 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1586 VM_Warning("effect: framecount < 1\n");
1590 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1592 VM_Warning("effect: framerate < 1\n");
1596 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));
1599 static void VM_SV_te_blood (void)
1601 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1602 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1604 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1605 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1607 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1608 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1609 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1611 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1612 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1613 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1615 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1616 SV_FlushBroadcastMessages();
1619 static void VM_SV_te_bloodshower (void)
1621 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1622 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1624 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1625 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1627 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1628 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1629 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1631 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1632 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1633 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1635 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1637 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1638 SV_FlushBroadcastMessages();
1641 static void VM_SV_te_explosionrgb (void)
1643 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1644 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1645 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1651 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1652 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1653 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1654 SV_FlushBroadcastMessages();
1657 static void VM_SV_te_particlecube (void)
1659 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1660 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1662 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1663 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1665 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1677 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1679 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1680 // gravity true/false
1681 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1683 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1684 SV_FlushBroadcastMessages();
1687 static void VM_SV_te_particlerain (void)
1689 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1690 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1692 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1693 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
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_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1700 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1701 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1703 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1704 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1705 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1707 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1709 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1710 SV_FlushBroadcastMessages();
1713 static void VM_SV_te_particlesnow (void)
1715 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1716 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1718 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1719 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1727 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1729 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1731 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1733 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1735 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1736 SV_FlushBroadcastMessages();
1739 static void VM_SV_te_spark (void)
1741 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1742 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1744 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1745 MSG_WriteByte(&sv.datagram, TE_SPARK);
1747 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1748 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1749 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1751 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1752 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1753 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1755 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1756 SV_FlushBroadcastMessages();
1759 static void VM_SV_te_gunshotquad (void)
1761 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1762 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1763 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1768 SV_FlushBroadcastMessages();
1771 static void VM_SV_te_spikequad (void)
1773 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1774 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1775 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1777 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1778 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1779 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1780 SV_FlushBroadcastMessages();
1783 static void VM_SV_te_superspikequad (void)
1785 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1786 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1787 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1792 SV_FlushBroadcastMessages();
1795 static void VM_SV_te_explosionquad (void)
1797 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1798 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1799 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1801 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1803 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1804 SV_FlushBroadcastMessages();
1807 static void VM_SV_te_smallflash (void)
1809 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1810 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1811 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1816 SV_FlushBroadcastMessages();
1819 static void VM_SV_te_customflash (void)
1821 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1822 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1824 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1825 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1827 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1831 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1833 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1835 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1836 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1837 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1838 SV_FlushBroadcastMessages();
1841 static void VM_SV_te_gunshot (void)
1843 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1844 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1845 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1847 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1848 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1849 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1850 SV_FlushBroadcastMessages();
1853 static void VM_SV_te_spike (void)
1855 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1856 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1857 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1862 SV_FlushBroadcastMessages();
1865 static void VM_SV_te_superspike (void)
1867 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1868 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1869 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1874 SV_FlushBroadcastMessages();
1877 static void VM_SV_te_explosion (void)
1879 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1880 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1881 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1883 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1884 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1885 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1886 SV_FlushBroadcastMessages();
1889 static void VM_SV_te_tarexplosion (void)
1891 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1892 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1893 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1895 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1898 SV_FlushBroadcastMessages();
1901 static void VM_SV_te_wizspike (void)
1903 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1904 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1905 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1909 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1910 SV_FlushBroadcastMessages();
1913 static void VM_SV_te_knightspike (void)
1915 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1916 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1917 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1922 SV_FlushBroadcastMessages();
1925 static void VM_SV_te_lavasplash (void)
1927 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1928 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1929 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1934 SV_FlushBroadcastMessages();
1937 static void VM_SV_te_teleport (void)
1939 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1940 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1941 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1946 SV_FlushBroadcastMessages();
1949 static void VM_SV_te_explosion2 (void)
1951 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1952 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1953 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1959 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1960 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1961 SV_FlushBroadcastMessages();
1964 static void VM_SV_te_lightning1 (void)
1966 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1967 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1968 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1970 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1978 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1979 SV_FlushBroadcastMessages();
1982 static void VM_SV_te_lightning2 (void)
1984 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1985 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1986 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1988 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1997 SV_FlushBroadcastMessages();
2000 static void VM_SV_te_lightning3 (void)
2002 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2003 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2004 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2006 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2010 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2014 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2015 SV_FlushBroadcastMessages();
2018 static void VM_SV_te_beam (void)
2020 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2021 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2022 MSG_WriteByte(&sv.datagram, TE_BEAM);
2024 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2026 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2027 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2028 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2033 SV_FlushBroadcastMessages();
2036 static void VM_SV_te_plasmaburn (void)
2038 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2039 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2040 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2041 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2042 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2043 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2044 SV_FlushBroadcastMessages();
2047 static void VM_SV_te_flamejet (void)
2049 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2050 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2051 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2055 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2058 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2059 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2061 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2062 SV_FlushBroadcastMessages();
2065 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2068 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2070 bestdist = 1000000000;
2072 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2074 // clip original point to each triangle of the surface and find the
2075 // triangle that is closest
2076 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2077 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2078 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2079 TriangleNormal(v[0], v[1], v[2], facenormal);
2080 VectorNormalize(facenormal);
2081 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2082 VectorMA(p, offsetdist, facenormal, temp);
2083 for (j = 0, k = 2;j < 3;k = j, j++)
2085 VectorSubtract(v[k], v[j], edgenormal);
2086 CrossProduct(edgenormal, facenormal, sidenormal);
2087 VectorNormalize(sidenormal);
2088 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2090 VectorMA(temp, offsetdist, sidenormal, temp);
2092 dist = VectorDistance2(temp, p);
2093 if (bestdist > dist)
2096 VectorCopy(temp, out);
2101 static model_t *getmodel(prvm_edict_t *ed)
2104 if (!ed || ed->priv.server->free)
2106 modelindex = (int)ed->fields.server->modelindex;
2107 if (modelindex < 1 || modelindex >= MAX_MODELS)
2109 return sv.models[modelindex];
2112 static msurface_t *getsurface(model_t *model, int surfacenum)
2114 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2116 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2120 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2121 static void VM_SV_getsurfacenumpoints(void)
2124 msurface_t *surface;
2125 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2126 // return 0 if no such surface
2127 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2129 PRVM_G_FLOAT(OFS_RETURN) = 0;
2133 // note: this (incorrectly) assumes it is a simple polygon
2134 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2136 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2137 static void VM_SV_getsurfacepoint(void)
2141 msurface_t *surface;
2143 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2144 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2145 ed = PRVM_G_EDICT(OFS_PARM0);
2146 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2148 // note: this (incorrectly) assumes it is a simple polygon
2149 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2150 if (pointnum < 0 || pointnum >= surface->num_vertices)
2152 // FIXME: implement rotation/scaling
2153 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2155 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2156 // float SPA_POSITION = 0;
2157 // float SPA_S_AXIS = 1;
2158 // float SPA_R_AXIS = 2;
2159 // float SPA_T_AXIS = 3; // same as SPA_NORMAL
2160 // float SPA_TEXCOORDS0 = 4;
2161 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2162 // float SPA_LIGHTMAP0_COLOR = 6;
2163 static void VM_SV_getsurfacepointattribute(void)
2167 msurface_t *surface;
2171 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2172 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2173 ed = PRVM_G_EDICT(OFS_PARM0);
2174 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2176 // note: this (incorrectly) assumes it is a simple polygon
2177 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2178 if (pointnum < 0 || pointnum >= surface->num_vertices)
2180 // FIXME: implement rotation/scaling
2181 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2183 switch( attributetype ) {
2184 // float SPA_POSITION = 0;
2186 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2188 // float SPA_S_AXIS = 1;
2190 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2192 // float SPA_R_AXIS = 2;
2194 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2196 // float SPA_T_AXIS = 3; // same as SPA_NORMAL
2198 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2200 // float SPA_TEXCOORDS0 = 4;
2202 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2203 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2204 ret[0] = texcoord[0];
2205 ret[1] = texcoord[1];
2209 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2211 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2212 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2213 ret[0] = texcoord[0];
2214 ret[1] = texcoord[1];
2218 // float SPA_LIGHTMAP0_COLOR = 6;
2220 // ignore alpha for now..
2221 VectorCopy( &(model->surfmesh.data_normal3f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2224 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2228 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2229 static void VM_SV_getsurfacenormal(void)
2232 msurface_t *surface;
2234 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2235 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2236 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2238 // FIXME: implement rotation/scaling
2239 // note: this (incorrectly) assumes it is a simple polygon
2240 // note: this only returns the first triangle, so it doesn't work very
2241 // well for curved surfaces or arbitrary meshes
2242 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);
2243 VectorNormalize(normal);
2244 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2246 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2247 static void VM_SV_getsurfacetexture(void)
2250 msurface_t *surface;
2251 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2252 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2253 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2255 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2257 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2258 static void VM_SV_getsurfacenearpoint(void)
2260 int surfacenum, best;
2262 vec_t dist, bestdist;
2265 msurface_t *surface;
2267 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2268 PRVM_G_FLOAT(OFS_RETURN) = -1;
2269 ed = PRVM_G_EDICT(OFS_PARM0);
2270 point = PRVM_G_VECTOR(OFS_PARM1);
2272 if (!ed || ed->priv.server->free)
2274 model = getmodel(ed);
2275 if (!model || !model->num_surfaces)
2278 // FIXME: implement rotation/scaling
2279 VectorSubtract(point, ed->fields.server->origin, p);
2281 bestdist = 1000000000;
2282 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2284 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2285 // first see if the nearest point on the surface's box is closer than the previous match
2286 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2287 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2288 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2289 dist = VectorLength2(clipped);
2290 if (dist < bestdist)
2292 // it is, check the nearest point on the actual geometry
2293 clippointtosurface(model, surface, p, clipped);
2294 VectorSubtract(clipped, p, clipped);
2295 dist += VectorLength2(clipped);
2296 if (dist < bestdist)
2298 // that's closer too, store it as the best match
2304 PRVM_G_FLOAT(OFS_RETURN) = best;
2306 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2307 static void VM_SV_getsurfaceclippedpoint(void)
2311 msurface_t *surface;
2313 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2314 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2315 ed = PRVM_G_EDICT(OFS_PARM0);
2316 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2318 // FIXME: implement rotation/scaling
2319 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2320 clippointtosurface(model, surface, p, out);
2321 // FIXME: implement rotation/scaling
2322 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2325 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2326 //this function originally written by KrimZon, made shorter by LordHavoc
2327 static void VM_SV_clientcommand (void)
2329 client_t *temp_client;
2331 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2333 //find client for this entity
2334 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2335 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2337 Con_Print("PF_clientcommand: entity is not a client\n");
2341 temp_client = host_client;
2342 host_client = svs.clients + i;
2343 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2344 host_client = temp_client;
2347 //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)
2348 static void VM_SV_setattachment (void)
2350 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2351 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2352 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2356 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2358 if (e == prog->edicts)
2360 VM_Warning("setattachment: can not modify world entity\n");
2363 if (e->priv.server->free)
2365 VM_Warning("setattachment: can not modify free entity\n");
2369 if (tagentity == NULL)
2370 tagentity = prog->edicts;
2372 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2374 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2376 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2379 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2381 modelindex = (int)tagentity->fields.server->modelindex;
2382 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2384 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2386 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);
2389 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));
2393 /////////////////////////////////////////
2394 // DP_MD3_TAGINFO extension coded by VorteX
2396 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2401 i = (int)e->fields.server->modelindex;
2402 if (i < 1 || i >= MAX_MODELS)
2404 model = sv.models[i];
2406 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2409 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2411 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2415 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);
2417 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);
2420 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2426 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2427 && (model = sv.models[(int)ent->fields.server->modelindex])
2428 && model->animscenes)
2430 // if model has wrong frame, engine automatically switches to model first frame
2431 frame = (int)ent->fields.server->frame;
2432 if (frame < 0 || frame >= model->numframes)
2434 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2436 *out = identitymatrix;
2440 // Warnings/errors code:
2441 // 0 - normal (everything all-right)
2444 // 3 - null or non-precached model
2445 // 4 - no tags with requested index
2446 // 5 - runaway loop at attachment chain
2447 extern cvar_t cl_bob;
2448 extern cvar_t cl_bobcycle;
2449 extern cvar_t cl_bobup;
2450 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2454 int modelindex, attachloop;
2455 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2458 *out = identitymatrix; // warnings and errors return identical matrix
2460 if (ent == prog->edicts)
2462 if (ent->priv.server->free)
2465 modelindex = (int)ent->fields.server->modelindex;
2466 if (modelindex <= 0 || modelindex > MAX_MODELS)
2469 model = sv.models[modelindex];
2471 tagmatrix = identitymatrix;
2472 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2476 if (attachloop >= 256) // prevent runaway looping
2478 // apply transformation by child's tagindex on parent entity and then
2479 // by parent entity itself
2480 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2481 if (ret && attachloop == 0)
2483 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2484 SV_GetEntityMatrix(ent, &entitymatrix, false);
2485 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2486 // next iteration we process the parent entity
2487 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2489 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2490 ent = PRVM_EDICT_NUM(val->edict);
2497 // RENDER_VIEWMODEL magic
2498 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2500 Matrix4x4_Copy(&tagmatrix, out);
2501 ent = PRVM_EDICT_NUM(val->edict);
2503 SV_GetEntityMatrix(ent, &entitymatrix, true);
2504 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2507 // Cl_bob, ported from rendering code
2508 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2511 // LordHavoc: this code is *weird*, but not replacable (I think it
2512 // should be done in QC on the server, but oh well, quake is quake)
2513 // LordHavoc: figured out bobup: the time at which the sin is at 180
2514 // degrees (which allows lengthening or squishing the peak or valley)
2515 cycle = sv.time/cl_bobcycle.value;
2516 cycle -= (int)cycle;
2517 if (cycle < cl_bobup.value)
2518 cycle = sin(M_PI * cycle / cl_bobup.value);
2520 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2521 // bob is proportional to velocity in the xy plane
2522 // (don't count Z, or jumping messes it up)
2523 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;
2524 bob = bob*0.3 + bob*0.7*cycle;
2525 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2532 //float(entity ent, string tagname) gettagindex;
2534 static void VM_SV_gettagindex (void)
2537 const char *tag_name;
2538 int modelindex, tag_index;
2540 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2542 ent = PRVM_G_EDICT(OFS_PARM0);
2543 tag_name = PRVM_G_STRING(OFS_PARM1);
2545 if (ent == prog->edicts)
2547 VM_Warning("gettagindex: can't affect world entity\n");
2550 if (ent->priv.server->free)
2552 VM_Warning("gettagindex: can't affect free entity\n");
2556 modelindex = (int)ent->fields.server->modelindex;
2558 if (modelindex <= 0 || modelindex > MAX_MODELS)
2559 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2562 tag_index = SV_GetTagIndex(ent, tag_name);
2564 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2566 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2569 //vector(entity ent, float tagindex) gettaginfo;
2570 static void VM_SV_gettaginfo (void)
2574 matrix4x4_t tag_matrix;
2577 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2579 e = PRVM_G_EDICT(OFS_PARM0);
2580 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2582 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2583 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2588 VM_Warning("gettagindex: can't affect world entity\n");
2591 VM_Warning("gettagindex: can't affect free entity\n");
2594 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2597 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2600 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2605 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2606 static void VM_SV_dropclient (void)
2609 client_t *oldhostclient;
2610 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2611 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2612 if (clientnum < 0 || clientnum >= svs.maxclients)
2614 VM_Warning("dropclient: not a client\n");
2617 if (!svs.clients[clientnum].active)
2619 VM_Warning("dropclient: that client slot is not connected\n");
2622 oldhostclient = host_client;
2623 host_client = svs.clients + clientnum;
2624 SV_DropClient(false);
2625 host_client = oldhostclient;
2628 //entity() spawnclient (DP_SV_BOTCLIENT)
2629 static void VM_SV_spawnclient (void)
2633 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2634 prog->xfunction->builtinsprofile += 2;
2636 for (i = 0;i < svs.maxclients;i++)
2638 if (!svs.clients[i].active)
2640 prog->xfunction->builtinsprofile += 100;
2641 SV_ConnectClient (i, NULL);
2642 // this has to be set or else ClientDisconnect won't be called
2643 // we assume the qc will call ClientConnect...
2644 svs.clients[i].clientconnectcalled = true;
2645 ed = PRVM_EDICT_NUM(i + 1);
2649 VM_RETURN_EDICT(ed);
2652 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2653 static void VM_SV_clienttype (void)
2656 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2657 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2658 if (clientnum < 0 || clientnum >= svs.maxclients)
2659 PRVM_G_FLOAT(OFS_RETURN) = 3;
2660 else if (!svs.clients[clientnum].active)
2661 PRVM_G_FLOAT(OFS_RETURN) = 0;
2662 else if (svs.clients[clientnum].netconnection)
2663 PRVM_G_FLOAT(OFS_RETURN) = 1;
2665 PRVM_G_FLOAT(OFS_RETURN) = 2;
2672 string(string key) serverkey
2675 void VM_SV_serverkey(void)
2677 char string[VM_STRINGTEMP_LENGTH];
2678 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2679 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2680 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2683 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2684 static void VM_SV_setmodelindex (void)
2689 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2691 e = PRVM_G_EDICT(OFS_PARM0);
2692 if (e == prog->edicts)
2694 VM_Warning("setmodelindex: can not modify world entity\n");
2697 if (e->priv.server->free)
2699 VM_Warning("setmodelindex: can not modify free entity\n");
2702 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2703 if (i <= 0 || i > MAX_MODELS)
2705 VM_Warning("setmodelindex: invalid modelindex\n");
2708 if (!sv.model_precache[i][0])
2710 VM_Warning("setmodelindex: model not precached\n");
2714 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2715 e->fields.server->modelindex = i;
2721 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2722 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2724 SetMinMaxSize (e, quakemins, quakemaxs, true);
2727 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2730 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2731 static void VM_SV_modelnameforindex (void)
2734 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2736 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2738 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2739 if (i <= 0 || i > MAX_MODELS)
2741 VM_Warning("modelnameforindex: invalid modelindex\n");
2744 if (!sv.model_precache[i][0])
2746 VM_Warning("modelnameforindex: model not precached\n");
2750 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2753 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2754 static void VM_SV_particleeffectnum (void)
2757 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2758 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2761 PRVM_G_FLOAT(OFS_RETURN) = i;
2764 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2765 static void VM_SV_trailparticles (void)
2767 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2769 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2770 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2771 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2772 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2773 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2774 SV_FlushBroadcastMessages();
2777 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2778 static void VM_SV_pointparticles (void)
2780 int effectnum, count;
2782 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2783 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2784 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2785 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2786 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2787 if (count == 1 && !VectorLength2(vel))
2790 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2791 MSG_WriteShort(&sv.datagram, effectnum);
2792 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2796 // 1+2+12+12+2=29 bytes
2797 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2798 MSG_WriteShort(&sv.datagram, effectnum);
2799 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2800 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2801 MSG_WriteShort(&sv.datagram, count);
2804 SV_FlushBroadcastMessages();
2807 prvm_builtin_t vm_sv_builtins[] = {
2808 NULL, // #0 NULL function (not callable) (QUAKE)
2809 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2810 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2811 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2812 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2813 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2814 VM_break, // #6 void() break (QUAKE)
2815 VM_random, // #7 float() random (QUAKE)
2816 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2817 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2818 VM_error, // #10 void(string e) error (QUAKE)
2819 VM_objerror, // #11 void(string e) objerror (QUAKE)
2820 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2821 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2822 VM_spawn, // #14 entity() spawn (QUAKE)
2823 VM_remove, // #15 void(entity e) remove (QUAKE)
2824 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2825 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2826 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2827 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2828 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2829 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2830 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2831 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2832 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2833 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2834 VM_ftos, // #26 string(float f) ftos (QUAKE)
2835 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2836 VM_coredump, // #28 void() coredump (QUAKE)
2837 VM_traceon, // #29 void() traceon (QUAKE)
2838 VM_traceoff, // #30 void() traceoff (QUAKE)
2839 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2840 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2841 NULL, // #33 (QUAKE)
2842 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2843 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2844 VM_rint, // #36 float(float v) rint (QUAKE)
2845 VM_floor, // #37 float(float v) floor (QUAKE)
2846 VM_ceil, // #38 float(float v) ceil (QUAKE)
2847 NULL, // #39 (QUAKE)
2848 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2849 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2850 NULL, // #42 (QUAKE)
2851 VM_fabs, // #43 float(float f) fabs (QUAKE)
2852 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2853 VM_cvar, // #45 float(string s) cvar (QUAKE)
2854 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2855 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2856 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2857 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2858 NULL, // #50 (QUAKE)
2859 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2860 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2861 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2862 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2863 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2864 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2865 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2866 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2867 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2868 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2869 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2870 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2871 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2872 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2873 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2874 NULL, // #66 (QUAKE)
2875 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2876 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2877 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2878 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2879 NULL, // #71 (QUAKE)
2880 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2881 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2882 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2883 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2884 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2885 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2886 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2887 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2888 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2889 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2890 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2891 NULL, // #83 (QUAKE)
2892 NULL, // #84 (QUAKE)
2893 NULL, // #85 (QUAKE)
2894 NULL, // #86 (QUAKE)
2895 NULL, // #87 (QUAKE)
2896 NULL, // #88 (QUAKE)
2897 NULL, // #89 (QUAKE)
2898 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2899 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2900 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2901 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2902 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2903 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2904 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2905 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2906 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2907 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2908 // FrikaC and Telejano range #100-#199
2919 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2920 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2921 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2922 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2923 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2924 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2925 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2926 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2927 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2928 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3009 // FTEQW range #200-#299
3028 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3031 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3032 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3033 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3034 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3035 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3036 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3037 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3038 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3039 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3040 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3042 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3110 // CSQC range #300-#399
3111 NULL, // #300 void() clearscene (EXT_CSQC)
3112 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3113 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3114 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3115 NULL, // #304 void() renderscene (EXT_CSQC)
3116 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3117 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3118 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3119 NULL, // #308 void() R_EndPolygon
3121 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3122 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3126 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3127 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3128 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3129 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3130 NULL, // #319 void(string name) freepic (EXT_CSQC)
3131 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3132 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3133 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3134 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3135 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3136 NULL, // #325 void(void) drawresetcliparea
3141 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3142 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3143 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3144 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3145 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3146 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3147 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3148 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3149 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3150 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3151 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3152 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3153 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3154 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3155 NULL, // #344 vector() getmousepos (EXT_CSQC)
3156 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3157 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3158 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3159 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3160 NULL, // #349 float() isdemo (EXT_CSQC)
3161 VM_isserver, // #350 float() isserver (EXT_CSQC)
3162 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3163 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3164 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3165 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3171 NULL, // #360 float() readbyte (EXT_CSQC)
3172 NULL, // #361 float() readchar (EXT_CSQC)
3173 NULL, // #362 float() readshort (EXT_CSQC)
3174 NULL, // #363 float() readlong (EXT_CSQC)
3175 NULL, // #364 float() readcoord (EXT_CSQC)
3176 NULL, // #365 float() readangle (EXT_CSQC)
3177 NULL, // #366 string() readstring (EXT_CSQC)
3178 NULL, // #367 float() readfloat (EXT_CSQC)
3211 // LordHavoc's range #400-#499
3212 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3213 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3214 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3215 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3216 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3217 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3218 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3219 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3220 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)
3221 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3222 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3223 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3224 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3225 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3226 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3227 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3228 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3229 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3230 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3231 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3232 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3233 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3234 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3235 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3236 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3237 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3238 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3239 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3240 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3241 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3242 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3243 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3244 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3245 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3246 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3247 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3248 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3249 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3250 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3251 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3252 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3253 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3254 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3255 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3256 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3257 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3258 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3259 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3260 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3261 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3262 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3263 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3264 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3265 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3266 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3267 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3268 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3269 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3271 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3272 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3273 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3274 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3275 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3276 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3277 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3278 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3279 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3280 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3281 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3283 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3284 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3285 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3286 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3287 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3288 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3289 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3290 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3291 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3292 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3293 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3294 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3295 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3296 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3297 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3298 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3314 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3316 void VM_SV_Cmd_Init(void)
3321 void VM_SV_Cmd_Reset(void)