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 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
872 static void VM_SV_precache_model (void)
874 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
875 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
876 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
883 float(float yaw, float dist[, settrace]) walkmove
886 static void VM_SV_walkmove (void)
895 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
897 // assume failure if it returns early
898 PRVM_G_FLOAT(OFS_RETURN) = 0;
900 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
901 if (ent == prog->edicts)
903 VM_Warning("walkmove: can not modify world entity\n");
906 if (ent->priv.server->free)
908 VM_Warning("walkmove: can not modify free entity\n");
911 yaw = PRVM_G_FLOAT(OFS_PARM0);
912 dist = PRVM_G_FLOAT(OFS_PARM1);
913 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
915 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
918 yaw = yaw*M_PI*2 / 360;
920 move[0] = cos(yaw)*dist;
921 move[1] = sin(yaw)*dist;
924 // save program state, because SV_movestep may call other progs
925 oldf = prog->xfunction;
926 oldself = prog->globals.server->self;
928 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
931 // restore program state
932 prog->xfunction = oldf;
933 prog->globals.server->self = oldself;
943 static void VM_SV_droptofloor (void)
949 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
951 // assume failure if it returns early
952 PRVM_G_FLOAT(OFS_RETURN) = 0;
954 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
955 if (ent == prog->edicts)
957 VM_Warning("droptofloor: can not modify world entity\n");
960 if (ent->priv.server->free)
962 VM_Warning("droptofloor: can not modify free entity\n");
966 VectorCopy (ent->fields.server->origin, end);
969 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
971 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
973 if (trace.fraction < 1)
974 VectorCopy (trace.endpos, ent->fields.server->origin);
975 SV_LinkEdict (ent, false);
976 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
977 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
978 PRVM_G_FLOAT(OFS_RETURN) = 1;
979 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
980 ent->priv.server->suspendedinairflag = true;
988 void(float style, string value) lightstyle
991 static void VM_SV_lightstyle (void)
998 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1000 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1001 val = PRVM_G_STRING(OFS_PARM1);
1003 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1004 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1007 // change the string in sv
1008 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1010 // send message to all clients on this server
1011 if (sv.state != ss_active)
1014 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1016 if (client->active && client->netconnection)
1018 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1019 MSG_WriteChar (&client->netconnection->message,style);
1020 MSG_WriteString (&client->netconnection->message, val);
1030 static void VM_SV_checkbottom (void)
1032 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1033 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1041 static void VM_SV_pointcontents (void)
1043 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1044 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1051 Pick a vector for the player to shoot along
1052 vector aim(entity, missilespeed)
1055 static void VM_SV_aim (void)
1057 prvm_edict_t *ent, *check, *bestent;
1058 vec3_t start, dir, end, bestdir;
1061 float dist, bestdist;
1064 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1066 // assume failure if it returns early
1067 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1068 // if sv_aim is so high it can't possibly accept anything, skip out early
1069 if (sv_aim.value >= 1)
1072 ent = PRVM_G_EDICT(OFS_PARM0);
1073 if (ent == prog->edicts)
1075 VM_Warning("aim: can not use world entity\n");
1078 if (ent->priv.server->free)
1080 VM_Warning("aim: can not use free entity\n");
1083 speed = PRVM_G_FLOAT(OFS_PARM1);
1085 VectorCopy (ent->fields.server->origin, start);
1088 // try sending a trace straight
1089 VectorCopy (prog->globals.server->v_forward, dir);
1090 VectorMA (start, 2048, dir, end);
1091 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1092 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1093 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1095 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1100 // try all possible entities
1101 VectorCopy (dir, bestdir);
1102 bestdist = sv_aim.value;
1105 check = PRVM_NEXT_EDICT(prog->edicts);
1106 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1108 prog->xfunction->builtinsprofile++;
1109 if (check->fields.server->takedamage != DAMAGE_AIM)
1113 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1114 continue; // don't aim at teammate
1115 for (j=0 ; j<3 ; j++)
1116 end[j] = check->fields.server->origin[j]
1117 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1118 VectorSubtract (end, start, dir);
1119 VectorNormalize (dir);
1120 dist = DotProduct (dir, prog->globals.server->v_forward);
1121 if (dist < bestdist)
1122 continue; // to far to turn
1123 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1124 if (tr.ent == check)
1125 { // can shoot at this one
1133 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1134 dist = DotProduct (dir, prog->globals.server->v_forward);
1135 VectorScale (prog->globals.server->v_forward, dist, end);
1137 VectorNormalize (end);
1138 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1142 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1147 ===============================================================================
1151 ===============================================================================
1154 #define MSG_BROADCAST 0 // unreliable to all
1155 #define MSG_ONE 1 // reliable to one (msg_entity)
1156 #define MSG_ALL 2 // reliable to all
1157 #define MSG_INIT 3 // write to the init string
1158 #define MSG_ENTITY 5
1160 sizebuf_t *WriteDest (void)
1166 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1170 return &sv.datagram;
1173 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1174 entnum = PRVM_NUM_FOR_EDICT(ent);
1175 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1177 VM_Warning ("WriteDest: tried to write to non-client\n");
1178 return &sv.reliable_datagram;
1181 return &svs.clients[entnum-1].netconnection->message;
1184 VM_Warning ("WriteDest: bad destination\n");
1186 return &sv.reliable_datagram;
1192 return sv.writeentitiestoclient_msg;
1198 static void VM_SV_WriteByte (void)
1200 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1201 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1204 static void VM_SV_WriteChar (void)
1206 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1207 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1210 static void VM_SV_WriteShort (void)
1212 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1213 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1216 static void VM_SV_WriteLong (void)
1218 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1219 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1222 static void VM_SV_WriteAngle (void)
1224 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1225 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1228 static void VM_SV_WriteCoord (void)
1230 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1231 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1234 static void VM_SV_WriteString (void)
1236 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1237 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1240 static void VM_SV_WriteUnterminatedString (void)
1242 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1243 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1247 static void VM_SV_WriteEntity (void)
1249 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1250 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1253 //////////////////////////////////////////////////////////
1255 static void VM_SV_makestatic (void)
1260 // allow 0 parameters due to an id1 qc bug in which this function is used
1261 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1262 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1264 if (prog->argc >= 1)
1265 ent = PRVM_G_EDICT(OFS_PARM0);
1267 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1268 if (ent == prog->edicts)
1270 VM_Warning("makestatic: can not modify world entity\n");
1273 if (ent->priv.server->free)
1275 VM_Warning("makestatic: can not modify free entity\n");
1280 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1285 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1286 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1287 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1289 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1291 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1292 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1293 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1297 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1298 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1299 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1302 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1303 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1304 for (i=0 ; i<3 ; i++)
1306 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1307 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1310 // throw the entity away now
1314 //=============================================================================
1321 static void VM_SV_setspawnparms (void)
1327 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1329 ent = PRVM_G_EDICT(OFS_PARM0);
1330 i = PRVM_NUM_FOR_EDICT(ent);
1331 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1333 Con_Print("tried to setspawnparms on a non-client\n");
1337 // copy spawn parms out of the client_t
1338 client = svs.clients + i-1;
1339 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1340 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1347 Returns a color vector indicating the lighting at the requested point.
1349 (Internal Operation note: actually measures the light beneath the point, just like
1350 the model lighting on the client)
1355 static void VM_SV_getlight (void)
1357 vec3_t ambientcolor, diffusecolor, diffusenormal;
1359 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1360 p = PRVM_G_VECTOR(OFS_PARM0);
1361 VectorClear(ambientcolor);
1362 VectorClear(diffusecolor);
1363 VectorClear(diffusenormal);
1364 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1365 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1366 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1371 unsigned char type; // 1/2/8 or other value if isn't used
1375 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1376 static int vm_customstats_last;
1378 void VM_CustomStats_Clear (void)
1382 Z_Free(vm_customstats);
1383 vm_customstats = NULL;
1384 vm_customstats_last = -1;
1388 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1396 for(i=0; i<vm_customstats_last+1 ;i++)
1398 if(!vm_customstats[i].type)
1400 switch(vm_customstats[i].type)
1402 //string as 16 bytes
1405 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1406 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1407 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1408 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1409 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1411 //float field sent as-is
1413 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1415 //integer value of float field
1417 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1425 // void(float index, float type, .void field) SV_AddStat = #232;
1426 // Set up an auto-sent player stat.
1427 // Client's get thier own fields sent to them. Index may not be less than 32.
1428 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1429 // 1: string (4 stats carrying a total of 16 charactures)
1430 // 2: float (one stat, float converted to an integer for transportation)
1431 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1432 static void VM_SV_AddStat (void)
1437 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1441 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1444 VM_Warning("PF_SV_AddStat: not enough memory\n");
1448 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1449 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1450 off = PRVM_G_INT (OFS_PARM2);
1455 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1458 if(i >= (MAX_CL_STATS-32))
1460 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1463 if(i > (MAX_CL_STATS-32-4) && type == 1)
1465 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1468 vm_customstats[i].type = type;
1469 vm_customstats[i].fieldoffset = off;
1470 if(vm_customstats_last < i)
1471 vm_customstats_last = i;
1478 copies data from one entity to another
1480 copyentity(src, dst)
1483 static void VM_SV_copyentity (void)
1485 prvm_edict_t *in, *out;
1486 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1487 in = PRVM_G_EDICT(OFS_PARM0);
1488 if (in == prog->edicts)
1490 VM_Warning("copyentity: can not read world entity\n");
1493 if (in->priv.server->free)
1495 VM_Warning("copyentity: can not read free entity\n");
1498 out = PRVM_G_EDICT(OFS_PARM1);
1499 if (out == prog->edicts)
1501 VM_Warning("copyentity: can not modify world entity\n");
1504 if (out->priv.server->free)
1506 VM_Warning("copyentity: can not modify free entity\n");
1509 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1510 SV_LinkEdict(out, false);
1518 sets the color of a client and broadcasts the update to all connected clients
1520 setcolor(clientent, value)
1523 static void VM_SV_setcolor (void)
1529 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1530 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1531 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1533 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1535 Con_Print("tried to setcolor a non-client\n");
1539 client = svs.clients + entnum-1;
1542 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1544 client->edict->fields.server->team = (i & 15) + 1;
1547 if (client->old_colors != client->colors)
1549 client->old_colors = client->colors;
1550 // send notification to all clients
1551 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1552 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1553 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1561 effect(origin, modelname, startframe, framecount, framerate)
1564 static void VM_SV_effect (void)
1568 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1569 s = PRVM_G_STRING(OFS_PARM1);
1572 VM_Warning("effect: no model specified\n");
1576 i = SV_ModelIndex(s, 1);
1579 VM_Warning("effect: model not precached\n");
1583 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1585 VM_Warning("effect: framecount < 1\n");
1589 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1591 VM_Warning("effect: framerate < 1\n");
1595 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));
1598 static void VM_SV_te_blood (void)
1600 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1601 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1603 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1604 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1606 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1607 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1608 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1610 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1611 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1612 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1614 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1615 SV_FlushBroadcastMessages();
1618 static void VM_SV_te_bloodshower (void)
1620 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1621 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1623 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1624 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1626 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1627 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1628 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1630 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1631 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1632 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1634 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1636 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1637 SV_FlushBroadcastMessages();
1640 static void VM_SV_te_explosionrgb (void)
1642 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1643 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1644 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1650 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1651 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1652 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1653 SV_FlushBroadcastMessages();
1656 static void VM_SV_te_particlecube (void)
1658 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1659 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1661 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1662 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1664 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1665 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1676 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1678 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1679 // gravity true/false
1680 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1682 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1683 SV_FlushBroadcastMessages();
1686 static void VM_SV_te_particlerain (void)
1688 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1689 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1691 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1692 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1696 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1698 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1699 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1700 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1702 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1703 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1704 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1706 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1708 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1709 SV_FlushBroadcastMessages();
1712 static void VM_SV_te_particlesnow (void)
1714 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1715 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1717 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1718 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1728 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1729 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1732 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1734 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1735 SV_FlushBroadcastMessages();
1738 static void VM_SV_te_spark (void)
1740 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1741 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1743 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1744 MSG_WriteByte(&sv.datagram, TE_SPARK);
1746 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1747 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1748 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1750 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1751 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1752 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1754 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1755 SV_FlushBroadcastMessages();
1758 static void VM_SV_te_gunshotquad (void)
1760 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1761 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1762 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1764 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1767 SV_FlushBroadcastMessages();
1770 static void VM_SV_te_spikequad (void)
1772 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1773 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1774 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1776 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1777 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1778 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1779 SV_FlushBroadcastMessages();
1782 static void VM_SV_te_superspikequad (void)
1784 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1785 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1786 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1791 SV_FlushBroadcastMessages();
1794 static void VM_SV_te_explosionquad (void)
1796 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1797 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1798 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1800 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1801 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1803 SV_FlushBroadcastMessages();
1806 static void VM_SV_te_smallflash (void)
1808 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1809 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1810 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1815 SV_FlushBroadcastMessages();
1818 static void VM_SV_te_customflash (void)
1820 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1821 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1823 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1824 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1826 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1827 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1830 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1832 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1834 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1835 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1836 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1837 SV_FlushBroadcastMessages();
1840 static void VM_SV_te_gunshot (void)
1842 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1843 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1844 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1846 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1847 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1848 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1849 SV_FlushBroadcastMessages();
1852 static void VM_SV_te_spike (void)
1854 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1855 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1856 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1861 SV_FlushBroadcastMessages();
1864 static void VM_SV_te_superspike (void)
1866 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1867 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1868 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1873 SV_FlushBroadcastMessages();
1876 static void VM_SV_te_explosion (void)
1878 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1879 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1880 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1882 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1883 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1884 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1885 SV_FlushBroadcastMessages();
1888 static void VM_SV_te_tarexplosion (void)
1890 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1891 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1892 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1895 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1897 SV_FlushBroadcastMessages();
1900 static void VM_SV_te_wizspike (void)
1902 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1903 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1904 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1909 SV_FlushBroadcastMessages();
1912 static void VM_SV_te_knightspike (void)
1914 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1915 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1916 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1921 SV_FlushBroadcastMessages();
1924 static void VM_SV_te_lavasplash (void)
1926 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1927 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1928 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1933 SV_FlushBroadcastMessages();
1936 static void VM_SV_te_teleport (void)
1938 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1939 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1940 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1945 SV_FlushBroadcastMessages();
1948 static void VM_SV_te_explosion2 (void)
1950 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1951 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1952 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1958 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1959 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1960 SV_FlushBroadcastMessages();
1963 static void VM_SV_te_lightning1 (void)
1965 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1966 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1967 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1969 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1978 SV_FlushBroadcastMessages();
1981 static void VM_SV_te_lightning2 (void)
1983 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1984 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1985 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1987 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1996 SV_FlushBroadcastMessages();
1999 static void VM_SV_te_lightning3 (void)
2001 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2002 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2003 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2005 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2014 SV_FlushBroadcastMessages();
2017 static void VM_SV_te_beam (void)
2019 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2020 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2021 MSG_WriteByte(&sv.datagram, TE_BEAM);
2023 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2025 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2026 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2027 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2029 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2032 SV_FlushBroadcastMessages();
2035 static void VM_SV_te_plasmaburn (void)
2037 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2038 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2039 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2040 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2041 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2042 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2043 SV_FlushBroadcastMessages();
2046 static void VM_SV_te_flamejet (void)
2048 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2049 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2050 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2058 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2060 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2061 SV_FlushBroadcastMessages();
2064 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2067 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2069 bestdist = 1000000000;
2071 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2073 // clip original point to each triangle of the surface and find the
2074 // triangle that is closest
2075 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2076 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2077 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2078 TriangleNormal(v[0], v[1], v[2], facenormal);
2079 VectorNormalize(facenormal);
2080 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2081 VectorMA(p, offsetdist, facenormal, temp);
2082 for (j = 0, k = 2;j < 3;k = j, j++)
2084 VectorSubtract(v[k], v[j], edgenormal);
2085 CrossProduct(edgenormal, facenormal, sidenormal);
2086 VectorNormalize(sidenormal);
2087 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2089 VectorMA(temp, offsetdist, sidenormal, temp);
2091 dist = VectorDistance2(temp, p);
2092 if (bestdist > dist)
2095 VectorCopy(temp, out);
2100 static model_t *getmodel(prvm_edict_t *ed)
2103 if (!ed || ed->priv.server->free)
2105 modelindex = (int)ed->fields.server->modelindex;
2106 if (modelindex < 1 || modelindex >= MAX_MODELS)
2108 return sv.models[modelindex];
2111 static msurface_t *getsurface(model_t *model, int surfacenum)
2113 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2115 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2119 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2120 static void VM_SV_getsurfacenumpoints(void)
2123 msurface_t *surface;
2124 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2125 // return 0 if no such surface
2126 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2128 PRVM_G_FLOAT(OFS_RETURN) = 0;
2132 // note: this (incorrectly) assumes it is a simple polygon
2133 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2135 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2136 static void VM_SV_getsurfacepoint(void)
2140 msurface_t *surface;
2142 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2143 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2144 ed = PRVM_G_EDICT(OFS_PARM0);
2145 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2147 // note: this (incorrectly) assumes it is a simple polygon
2148 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2149 if (pointnum < 0 || pointnum >= surface->num_vertices)
2151 // FIXME: implement rotation/scaling
2152 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2154 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2155 // float SPA_POSITION = 0;
2156 // float SPA_S_AXIS = 1;
2157 // float SPA_R_AXIS = 2;
2158 // float SPA_T_AXIS = 3; // same as SPA_NORMAL
2159 // float SPA_TEXCOORDS0 = 4;
2160 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2161 // float SPA_LIGHTMAP0_COLOR = 6;
2162 static void VM_SV_getsurfacepointattribute(void)
2166 msurface_t *surface;
2170 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2171 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2172 ed = PRVM_G_EDICT(OFS_PARM0);
2173 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2175 // note: this (incorrectly) assumes it is a simple polygon
2176 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2177 if (pointnum < 0 || pointnum >= surface->num_vertices)
2179 // FIXME: implement rotation/scaling
2180 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2182 switch( attributetype ) {
2183 // float SPA_POSITION = 0;
2185 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2187 // float SPA_S_AXIS = 1;
2189 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2191 // float SPA_R_AXIS = 2;
2193 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2195 // float SPA_T_AXIS = 3; // same as SPA_NORMAL
2197 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2199 // float SPA_TEXCOORDS0 = 4;
2201 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2202 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2203 ret[0] = texcoord[0];
2204 ret[1] = texcoord[1];
2208 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2210 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2211 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2212 ret[0] = texcoord[0];
2213 ret[1] = texcoord[1];
2217 // float SPA_LIGHTMAP0_COLOR = 6;
2219 // ignore alpha for now..
2220 VectorCopy( &(model->surfmesh.data_normal3f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2223 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2227 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2228 static void VM_SV_getsurfacenormal(void)
2231 msurface_t *surface;
2233 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2234 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2235 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2237 // FIXME: implement rotation/scaling
2238 // note: this (incorrectly) assumes it is a simple polygon
2239 // note: this only returns the first triangle, so it doesn't work very
2240 // well for curved surfaces or arbitrary meshes
2241 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);
2242 VectorNormalize(normal);
2243 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2245 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2246 static void VM_SV_getsurfacetexture(void)
2249 msurface_t *surface;
2250 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2251 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2252 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2254 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2256 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2257 static void VM_SV_getsurfacenearpoint(void)
2259 int surfacenum, best;
2261 vec_t dist, bestdist;
2264 msurface_t *surface;
2266 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2267 PRVM_G_FLOAT(OFS_RETURN) = -1;
2268 ed = PRVM_G_EDICT(OFS_PARM0);
2269 point = PRVM_G_VECTOR(OFS_PARM1);
2271 if (!ed || ed->priv.server->free)
2273 model = getmodel(ed);
2274 if (!model || !model->num_surfaces)
2277 // FIXME: implement rotation/scaling
2278 VectorSubtract(point, ed->fields.server->origin, p);
2280 bestdist = 1000000000;
2281 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2283 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2284 // first see if the nearest point on the surface's box is closer than the previous match
2285 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2286 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2287 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2288 dist = VectorLength2(clipped);
2289 if (dist < bestdist)
2291 // it is, check the nearest point on the actual geometry
2292 clippointtosurface(model, surface, p, clipped);
2293 VectorSubtract(clipped, p, clipped);
2294 dist += VectorLength2(clipped);
2295 if (dist < bestdist)
2297 // that's closer too, store it as the best match
2303 PRVM_G_FLOAT(OFS_RETURN) = best;
2305 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2306 static void VM_SV_getsurfaceclippedpoint(void)
2310 msurface_t *surface;
2312 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2313 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2314 ed = PRVM_G_EDICT(OFS_PARM0);
2315 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2317 // FIXME: implement rotation/scaling
2318 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2319 clippointtosurface(model, surface, p, out);
2320 // FIXME: implement rotation/scaling
2321 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2324 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2325 //this function originally written by KrimZon, made shorter by LordHavoc
2326 static void VM_SV_clientcommand (void)
2328 client_t *temp_client;
2330 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2332 //find client for this entity
2333 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2334 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2336 Con_Print("PF_clientcommand: entity is not a client\n");
2340 temp_client = host_client;
2341 host_client = svs.clients + i;
2342 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2343 host_client = temp_client;
2346 //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)
2347 static void VM_SV_setattachment (void)
2349 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2350 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2351 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2355 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2357 if (e == prog->edicts)
2359 VM_Warning("setattachment: can not modify world entity\n");
2362 if (e->priv.server->free)
2364 VM_Warning("setattachment: can not modify free entity\n");
2368 if (tagentity == NULL)
2369 tagentity = prog->edicts;
2371 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2373 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2375 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2378 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2380 modelindex = (int)tagentity->fields.server->modelindex;
2381 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2383 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2385 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);
2388 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));
2392 /////////////////////////////////////////
2393 // DP_MD3_TAGINFO extension coded by VorteX
2395 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2400 i = (int)e->fields.server->modelindex;
2401 if (i < 1 || i >= MAX_MODELS)
2403 model = sv.models[i];
2405 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2408 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2410 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2414 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);
2416 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);
2419 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2425 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2426 && (model = sv.models[(int)ent->fields.server->modelindex])
2427 && model->animscenes)
2429 // if model has wrong frame, engine automatically switches to model first frame
2430 frame = (int)ent->fields.server->frame;
2431 if (frame < 0 || frame >= model->numframes)
2433 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2435 *out = identitymatrix;
2439 // Warnings/errors code:
2440 // 0 - normal (everything all-right)
2443 // 3 - null or non-precached model
2444 // 4 - no tags with requested index
2445 // 5 - runaway loop at attachment chain
2446 extern cvar_t cl_bob;
2447 extern cvar_t cl_bobcycle;
2448 extern cvar_t cl_bobup;
2449 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2453 int modelindex, attachloop;
2454 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2457 *out = identitymatrix; // warnings and errors return identical matrix
2459 if (ent == prog->edicts)
2461 if (ent->priv.server->free)
2464 modelindex = (int)ent->fields.server->modelindex;
2465 if (modelindex <= 0 || modelindex > MAX_MODELS)
2468 model = sv.models[modelindex];
2470 tagmatrix = identitymatrix;
2471 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2475 if (attachloop >= 256) // prevent runaway looping
2477 // apply transformation by child's tagindex on parent entity and then
2478 // by parent entity itself
2479 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2480 if (ret && attachloop == 0)
2482 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2483 SV_GetEntityMatrix(ent, &entitymatrix, false);
2484 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2485 // next iteration we process the parent entity
2486 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2488 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2489 ent = PRVM_EDICT_NUM(val->edict);
2496 // RENDER_VIEWMODEL magic
2497 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2499 Matrix4x4_Copy(&tagmatrix, out);
2500 ent = PRVM_EDICT_NUM(val->edict);
2502 SV_GetEntityMatrix(ent, &entitymatrix, true);
2503 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2506 // Cl_bob, ported from rendering code
2507 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2510 // LordHavoc: this code is *weird*, but not replacable (I think it
2511 // should be done in QC on the server, but oh well, quake is quake)
2512 // LordHavoc: figured out bobup: the time at which the sin is at 180
2513 // degrees (which allows lengthening or squishing the peak or valley)
2514 cycle = sv.time/cl_bobcycle.value;
2515 cycle -= (int)cycle;
2516 if (cycle < cl_bobup.value)
2517 cycle = sin(M_PI * cycle / cl_bobup.value);
2519 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2520 // bob is proportional to velocity in the xy plane
2521 // (don't count Z, or jumping messes it up)
2522 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;
2523 bob = bob*0.3 + bob*0.7*cycle;
2524 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2531 //float(entity ent, string tagname) gettagindex;
2533 static void VM_SV_gettagindex (void)
2536 const char *tag_name;
2537 int modelindex, tag_index;
2539 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2541 ent = PRVM_G_EDICT(OFS_PARM0);
2542 tag_name = PRVM_G_STRING(OFS_PARM1);
2544 if (ent == prog->edicts)
2546 VM_Warning("gettagindex: can't affect world entity\n");
2549 if (ent->priv.server->free)
2551 VM_Warning("gettagindex: can't affect free entity\n");
2555 modelindex = (int)ent->fields.server->modelindex;
2557 if (modelindex <= 0 || modelindex > MAX_MODELS)
2558 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2561 tag_index = SV_GetTagIndex(ent, tag_name);
2563 if(developer.integer >= 100)
2564 Con_Printf("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)