5 //============================================================================
10 char *vm_sv_extensions =
15 "DP_CON_ALIASPARAMETERS "
34 "DP_ENT_CUSTOMCOLORMAP "
35 "DP_ENT_EXTERIORMODELTOCLIENT "
37 "DP_ENT_LOWPRECISION "
41 "DP_GFX_EXTERNALTEXTURES "
42 "DP_GFX_EXTERNALTEXTURES_PERMAP "
44 "DP_GFX_QUAKE3MODELTAGS "
48 "DP_HALFLIFE_MAP_CVAR "
54 "DP_MOVETYPEBOUNCEMISSILE "
56 "DP_QC_ASINACOSATANATAN2TAN "
61 "DP_QC_CVAR_DEFSTRING "
67 "DP_QC_FINDCHAINFLAGS "
68 "DP_QC_FINDCHAINFLOAT "
74 "DP_QC_GETSURFACEPOINTATTRIBUTE "
77 "DP_QC_MULTIPLETEMPSTRINGS "
78 "DP_QC_NUM_FOR_EDICT "
80 "DP_QC_SINCOSSQRTPOW "
82 "DP_QC_STRINGBUFFERS "
83 "DP_QC_STRINGCOLORFUNCTIONS "
84 "DP_QC_STRING_CASE_FUNCTIONS "
86 "DP_QC_TOKENIZEBYSEPARATOR "
89 "DP_QC_TRACE_MOVETYPE_HITMODEL "
90 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
91 "DP_QC_UNLIMITEDTEMPSTRINGS "
93 "DP_QC_VECTOANGLES_WITH_ROLL "
94 "DP_QC_VECTORVECTORS "
100 "DP_SND_DIRECTIONLESSATTNNONE "
107 "DP_SV_CLIENTCOLORS "
110 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
111 "DP_SV_DRAWONLYTOCLIENT "
114 "DP_SV_ENTITYCONTENTSTRANSITION "
115 "DP_SV_MODELFLAGS_AS_EFFECTS "
116 "DP_SV_MOVETYPESTEP_LANDEVENT "
118 "DP_SV_NODRAWTOCLIENT "
119 "DP_SV_ONENTITYNOSPAWNFUNCTION "
121 "DP_SV_PLAYERPHYSICS "
122 "DP_SV_POINTPARTICLES "
124 "DP_SV_PRECACHEANYTIME "
127 "DP_SV_ROTATINGBMODEL "
131 "DP_SV_WRITEUNTERMINATEDSTRING "
135 "DP_TE_EXPLOSIONRGB "
137 "DP_TE_PARTICLECUBE "
138 "DP_TE_PARTICLERAIN "
139 "DP_TE_PARTICLESNOW "
141 "DP_TE_QUADEFFECTS1 "
144 "DP_TE_STANDARDEFFECTBUILTINS "
145 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
150 "KRIMZON_SV_PARSECLIENTCOMMAND "
153 "NEXUIZ_PLAYERMODEL "
155 "PRYDON_CLIENTCURSOR "
156 "TENEBRAE_GFX_DLIGHTS "
158 //"EXT_CSQC " // not ready yet
165 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.
167 setorigin (entity, origin)
170 static void VM_SV_setorigin (void)
175 VM_SAFEPARMCOUNT(2, VM_setorigin);
177 e = PRVM_G_EDICT(OFS_PARM0);
178 if (e == prog->edicts)
180 VM_Warning("setorigin: can not modify world entity\n");
183 if (e->priv.server->free)
185 VM_Warning("setorigin: can not modify free entity\n");
188 org = PRVM_G_VECTOR(OFS_PARM1);
189 VectorCopy (org, e->fields.server->origin);
190 SV_LinkEdict (e, false);
193 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
194 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
198 for (i=0 ; i<3 ; i++)
200 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
202 // set derived values
203 VectorCopy (min, e->fields.server->mins);
204 VectorCopy (max, e->fields.server->maxs);
205 VectorSubtract (max, min, e->fields.server->size);
207 SV_LinkEdict (e, false);
214 the size box is rotated by the current angle
215 LordHavoc: no it isn't...
217 setsize (entity, minvector, maxvector)
220 static void VM_SV_setsize (void)
225 VM_SAFEPARMCOUNT(3, VM_setsize);
227 e = PRVM_G_EDICT(OFS_PARM0);
228 if (e == prog->edicts)
230 VM_Warning("setsize: can not modify world entity\n");
233 if (e->priv.server->free)
235 VM_Warning("setsize: can not modify free entity\n");
238 min = PRVM_G_VECTOR(OFS_PARM1);
239 max = PRVM_G_VECTOR(OFS_PARM2);
240 SetMinMaxSize (e, min, max, false);
248 setmodel(entity, model)
251 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
252 static void VM_SV_setmodel (void)
258 VM_SAFEPARMCOUNT(2, VM_setmodel);
260 e = PRVM_G_EDICT(OFS_PARM0);
261 if (e == prog->edicts)
263 VM_Warning("setmodel: can not modify world entity\n");
266 if (e->priv.server->free)
268 VM_Warning("setmodel: can not modify free entity\n");
271 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
272 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
273 e->fields.server->modelindex = i;
279 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
280 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
282 SetMinMaxSize (e, quakemins, quakemaxs, true);
285 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
292 single print to a specific client
294 sprint(clientent, value)
297 static void VM_SV_sprint (void)
301 char string[VM_STRINGTEMP_LENGTH];
303 VM_VarString(1, string, sizeof(string));
305 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
307 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
308 // LordHavoc: div0 requested that sprintto world operate like print
315 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
317 VM_Warning("tried to centerprint to a non-client\n");
321 client = svs.clients + entnum-1;
322 if (!client->netconnection)
325 MSG_WriteChar(&client->netconnection->message,svc_print);
326 MSG_WriteString(&client->netconnection->message, string);
334 single print to a specific client
336 centerprint(clientent, value)
339 static void VM_SV_centerprint (void)
343 char string[VM_STRINGTEMP_LENGTH];
345 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
347 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
349 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
351 VM_Warning("tried to centerprint to a non-client\n");
355 client = svs.clients + entnum-1;
356 if (!client->netconnection)
359 VM_VarString(1, string, sizeof(string));
360 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
361 MSG_WriteString(&client->netconnection->message, string);
368 particle(origin, color, count)
371 static void VM_SV_particle (void)
377 VM_SAFEPARMCOUNT(4, VM_SV_particle);
379 org = PRVM_G_VECTOR(OFS_PARM0);
380 dir = PRVM_G_VECTOR(OFS_PARM1);
381 color = PRVM_G_FLOAT(OFS_PARM2);
382 count = PRVM_G_FLOAT(OFS_PARM3);
383 SV_StartParticle (org, dir, (int)color, (int)count);
393 static void VM_SV_ambientsound (void)
397 float vol, attenuation;
400 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
402 pos = PRVM_G_VECTOR (OFS_PARM0);
403 samp = PRVM_G_STRING(OFS_PARM1);
404 vol = PRVM_G_FLOAT(OFS_PARM2);
405 attenuation = PRVM_G_FLOAT(OFS_PARM3);
407 // check to see if samp was properly precached
408 soundnum = SV_SoundIndex(samp, 1);
416 // add an svc_spawnambient command to the level signon packet
419 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
421 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
423 MSG_WriteVector(&sv.signon, pos, sv.protocol);
425 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
426 MSG_WriteShort (&sv.signon, soundnum);
428 MSG_WriteByte (&sv.signon, soundnum);
430 MSG_WriteByte (&sv.signon, (int)(vol*255));
431 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
439 Each entity can have eight independant sound sources, like voice,
442 Channel 0 is an auto-allocate channel, the others override anything
443 already running on that entity/channel pair.
445 An attenuation of 0 will play full volume everywhere in the level.
446 Larger attenuations will drop off.
450 static void VM_SV_sound (void)
454 prvm_edict_t *entity;
458 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
460 entity = PRVM_G_EDICT(OFS_PARM0);
461 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
462 sample = PRVM_G_STRING(OFS_PARM2);
463 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
464 attenuation = PRVM_G_FLOAT(OFS_PARM4);
467 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
471 if (volume < 0 || volume > 255)
473 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
477 if (attenuation < 0 || attenuation > 4)
479 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
483 if (channel < 0 || channel > 7)
485 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
489 SV_StartSound (entity, channel, sample, volume, attenuation);
496 Follows the same logic as VM_SV_sound, except instead of
497 an entity, an origin for the sound is provided, and channel
498 is omitted (since no entity is being tracked).
502 static void VM_SV_pointsound(void)
509 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
511 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
512 sample = PRVM_G_STRING(OFS_PARM1);
513 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
514 attenuation = PRVM_G_FLOAT(OFS_PARM3);
516 if (volume < 0 || volume > 255)
518 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
522 if (attenuation < 0 || attenuation > 4)
524 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
528 SV_StartPointSound (org, sample, volume, attenuation);
535 Used for use tracing and shot targeting
536 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
537 if the tryents flag is set.
539 traceline (vector1, vector2, movetype, ignore)
542 static void VM_SV_traceline (void)
549 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
551 prog->xfunction->builtinsprofile += 30;
553 v1 = PRVM_G_VECTOR(OFS_PARM0);
554 v2 = PRVM_G_VECTOR(OFS_PARM1);
555 move = (int)PRVM_G_FLOAT(OFS_PARM2);
556 ent = PRVM_G_EDICT(OFS_PARM3);
558 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]))
559 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));
561 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
563 VM_SetTraceGlobals(&trace);
571 Used for use tracing and shot targeting
572 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
573 if the tryents flag is set.
575 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
578 // LordHavoc: added this for my own use, VERY useful, similar to traceline
579 static void VM_SV_tracebox (void)
581 float *v1, *v2, *m1, *m2;
586 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
588 prog->xfunction->builtinsprofile += 30;
590 v1 = PRVM_G_VECTOR(OFS_PARM0);
591 m1 = PRVM_G_VECTOR(OFS_PARM1);
592 m2 = PRVM_G_VECTOR(OFS_PARM2);
593 v2 = PRVM_G_VECTOR(OFS_PARM3);
594 move = (int)PRVM_G_FLOAT(OFS_PARM4);
595 ent = PRVM_G_EDICT(OFS_PARM5);
597 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]))
598 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));
600 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
602 VM_SetTraceGlobals(&trace);
605 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
610 vec3_t original_origin;
611 vec3_t original_velocity;
612 vec3_t original_angles;
613 vec3_t original_avelocity;
617 VectorCopy(tossent->fields.server->origin , original_origin );
618 VectorCopy(tossent->fields.server->velocity , original_velocity );
619 VectorCopy(tossent->fields.server->angles , original_angles );
620 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
622 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
623 if (val != NULL && val->_float != 0)
624 gravity = val->_float;
627 gravity *= sv_gravity.value * 0.05;
629 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
631 SV_CheckVelocity (tossent);
632 tossent->fields.server->velocity[2] -= gravity;
633 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
634 VectorScale (tossent->fields.server->velocity, 0.05, move);
635 VectorAdd (tossent->fields.server->origin, move, end);
636 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
637 VectorCopy (trace.endpos, tossent->fields.server->origin);
639 if (trace.fraction < 1)
643 VectorCopy(original_origin , tossent->fields.server->origin );
644 VectorCopy(original_velocity , tossent->fields.server->velocity );
645 VectorCopy(original_angles , tossent->fields.server->angles );
646 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
651 static void VM_SV_tracetoss (void)
655 prvm_edict_t *ignore;
657 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
659 prog->xfunction->builtinsprofile += 600;
661 ent = PRVM_G_EDICT(OFS_PARM0);
662 if (ent == prog->edicts)
664 VM_Warning("tracetoss: can not use world entity\n");
667 ignore = PRVM_G_EDICT(OFS_PARM1);
669 trace = SV_Trace_Toss (ent, ignore);
671 VM_SetTraceGlobals(&trace);
674 //============================================================================
676 static int checkpvsbytes;
677 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
679 static int VM_SV_newcheckclient (int check)
685 // cycle to the next one
687 check = bound(1, check, svs.maxclients);
688 if (check == svs.maxclients)
696 prog->xfunction->builtinsprofile++;
698 if (i == svs.maxclients+1)
700 // look up the client's edict
701 ent = PRVM_EDICT_NUM(i);
702 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
703 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
705 // found a valid client (possibly the same one again)
709 // get the PVS for the entity
710 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
712 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
713 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
722 Returns a client (or object that has a client enemy) that would be a
725 If there is more than one valid option, they are cycled each frame
727 If (self.origin + self.viewofs) is not in the PVS of the current target,
728 it is not returned at all.
733 int c_invis, c_notvis;
734 static void VM_SV_checkclient (void)
736 prvm_edict_t *ent, *self;
739 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
741 // find a new check if on a new frame
742 if (sv.time - sv.lastchecktime >= 0.1)
744 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
745 sv.lastchecktime = sv.time;
748 // return check if it might be visible
749 ent = PRVM_EDICT_NUM(sv.lastcheck);
750 if (ent->priv.server->free || ent->fields.server->health <= 0)
752 VM_RETURN_EDICT(prog->edicts);
756 // if current entity can't possibly see the check entity, return 0
757 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
758 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
759 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
762 VM_RETURN_EDICT(prog->edicts);
766 // might be able to see it
768 VM_RETURN_EDICT(ent);
771 //============================================================================
778 Sends text over to the client's execution buffer
780 stuffcmd (clientent, value, ...)
783 static void VM_SV_stuffcmd (void)
787 char string[VM_STRINGTEMP_LENGTH];
789 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
791 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
792 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
794 VM_Warning("Can't stuffcmd to a non-client\n");
798 VM_VarString(1, string, sizeof(string));
801 host_client = svs.clients + entnum-1;
802 Host_ClientCommands ("%s", string);
810 Returns a chain of entities that have origins within a spherical area
812 findradius (origin, radius)
815 static void VM_SV_findradius (void)
817 prvm_edict_t *ent, *chain;
818 vec_t radius, radius2;
819 vec3_t org, eorg, mins, maxs;
822 prvm_edict_t *touchedicts[MAX_EDICTS];
824 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
826 chain = (prvm_edict_t *)prog->edicts;
828 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
829 radius = PRVM_G_FLOAT(OFS_PARM1);
830 radius2 = radius * radius;
832 mins[0] = org[0] - (radius + 1);
833 mins[1] = org[1] - (radius + 1);
834 mins[2] = org[2] - (radius + 1);
835 maxs[0] = org[0] + (radius + 1);
836 maxs[1] = org[1] + (radius + 1);
837 maxs[2] = org[2] + (radius + 1);
838 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
839 if (numtouchedicts > MAX_EDICTS)
841 // this never happens
842 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
843 numtouchedicts = MAX_EDICTS;
845 for (i = 0;i < numtouchedicts;i++)
847 ent = touchedicts[i];
848 prog->xfunction->builtinsprofile++;
849 // Quake did not return non-solid entities but darkplaces does
850 // (note: this is the reason you can't blow up fallen zombies)
851 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
853 // LordHavoc: compare against bounding box rather than center so it
854 // doesn't miss large objects, and use DotProduct instead of Length
855 // for a major speedup
856 VectorSubtract(org, ent->fields.server->origin, eorg);
857 if (sv_gameplayfix_findradiusdistancetobox.integer)
859 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
860 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
861 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
864 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
865 if (DotProduct(eorg, eorg) < radius2)
867 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
872 VM_RETURN_EDICT(chain);
875 static void VM_SV_precache_sound (void)
877 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
878 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
881 static void VM_SV_precache_model (void)
883 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
884 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
885 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
892 float(float yaw, float dist[, settrace]) walkmove
895 static void VM_SV_walkmove (void)
904 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
906 // assume failure if it returns early
907 PRVM_G_FLOAT(OFS_RETURN) = 0;
909 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
910 if (ent == prog->edicts)
912 VM_Warning("walkmove: can not modify world entity\n");
915 if (ent->priv.server->free)
917 VM_Warning("walkmove: can not modify free entity\n");
920 yaw = PRVM_G_FLOAT(OFS_PARM0);
921 dist = PRVM_G_FLOAT(OFS_PARM1);
922 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
924 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
927 yaw = yaw*M_PI*2 / 360;
929 move[0] = cos(yaw)*dist;
930 move[1] = sin(yaw)*dist;
933 // save program state, because SV_movestep may call other progs
934 oldf = prog->xfunction;
935 oldself = prog->globals.server->self;
937 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
940 // restore program state
941 prog->xfunction = oldf;
942 prog->globals.server->self = oldself;
952 static void VM_SV_droptofloor (void)
958 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
960 // assume failure if it returns early
961 PRVM_G_FLOAT(OFS_RETURN) = 0;
963 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
964 if (ent == prog->edicts)
966 VM_Warning("droptofloor: can not modify world entity\n");
969 if (ent->priv.server->free)
971 VM_Warning("droptofloor: can not modify free entity\n");
975 VectorCopy (ent->fields.server->origin, end);
978 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
979 SV_UnstickEntity(ent);
981 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
982 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
985 VectorSet(offset, 0.5f * (ent->fields.server->mins[0] + ent->fields.server->maxs[0]), 0.5f * (ent->fields.server->mins[1] + ent->fields.server->maxs[1]), ent->fields.server->mins[2]);
986 VectorAdd(ent->fields.server->origin, offset, org);
987 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
988 VectorSubtract(trace.endpos, offset, trace.endpos);
989 if (trace.startsolid)
991 Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
992 SV_UnstickEntity(ent);
993 SV_LinkEdict (ent, false);
994 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
995 ent->fields.server->groundentity = 0;
996 PRVM_G_FLOAT(OFS_RETURN) = 1;
998 else if (trace.fraction < 1)
1000 Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
1001 VectorCopy (trace.endpos, ent->fields.server->origin);
1002 SV_UnstickEntity(ent);
1003 SV_LinkEdict (ent, false);
1004 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1005 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1006 PRVM_G_FLOAT(OFS_RETURN) = 1;
1007 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1008 ent->priv.server->suspendedinairflag = true;
1013 if (trace.fraction != 1)
1015 if (trace.fraction < 1)
1016 VectorCopy (trace.endpos, ent->fields.server->origin);
1017 SV_LinkEdict (ent, false);
1018 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1019 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1020 PRVM_G_FLOAT(OFS_RETURN) = 1;
1021 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1022 ent->priv.server->suspendedinairflag = true;
1031 void(float style, string value) lightstyle
1034 static void VM_SV_lightstyle (void)
1041 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1043 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1044 val = PRVM_G_STRING(OFS_PARM1);
1046 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1047 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1050 // change the string in sv
1051 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1053 // send message to all clients on this server
1054 if (sv.state != ss_active)
1057 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1059 if (client->active && client->netconnection)
1061 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1062 MSG_WriteChar (&client->netconnection->message,style);
1063 MSG_WriteString (&client->netconnection->message, val);
1073 static void VM_SV_checkbottom (void)
1075 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1076 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1084 static void VM_SV_pointcontents (void)
1086 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1087 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1094 Pick a vector for the player to shoot along
1095 vector aim(entity, missilespeed)
1098 static void VM_SV_aim (void)
1100 prvm_edict_t *ent, *check, *bestent;
1101 vec3_t start, dir, end, bestdir;
1104 float dist, bestdist;
1107 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1109 // assume failure if it returns early
1110 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1111 // if sv_aim is so high it can't possibly accept anything, skip out early
1112 if (sv_aim.value >= 1)
1115 ent = PRVM_G_EDICT(OFS_PARM0);
1116 if (ent == prog->edicts)
1118 VM_Warning("aim: can not use world entity\n");
1121 if (ent->priv.server->free)
1123 VM_Warning("aim: can not use free entity\n");
1126 speed = PRVM_G_FLOAT(OFS_PARM1);
1128 VectorCopy (ent->fields.server->origin, start);
1131 // try sending a trace straight
1132 VectorCopy (prog->globals.server->v_forward, dir);
1133 VectorMA (start, 2048, dir, end);
1134 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1135 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1136 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1138 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1143 // try all possible entities
1144 VectorCopy (dir, bestdir);
1145 bestdist = sv_aim.value;
1148 check = PRVM_NEXT_EDICT(prog->edicts);
1149 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1151 prog->xfunction->builtinsprofile++;
1152 if (check->fields.server->takedamage != DAMAGE_AIM)
1156 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1157 continue; // don't aim at teammate
1158 for (j=0 ; j<3 ; j++)
1159 end[j] = check->fields.server->origin[j]
1160 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1161 VectorSubtract (end, start, dir);
1162 VectorNormalize (dir);
1163 dist = DotProduct (dir, prog->globals.server->v_forward);
1164 if (dist < bestdist)
1165 continue; // to far to turn
1166 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1167 if (tr.ent == check)
1168 { // can shoot at this one
1176 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1177 dist = DotProduct (dir, prog->globals.server->v_forward);
1178 VectorScale (prog->globals.server->v_forward, dist, end);
1180 VectorNormalize (end);
1181 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1185 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1190 ===============================================================================
1194 ===============================================================================
1197 #define MSG_BROADCAST 0 // unreliable to all
1198 #define MSG_ONE 1 // reliable to one (msg_entity)
1199 #define MSG_ALL 2 // reliable to all
1200 #define MSG_INIT 3 // write to the init string
1201 #define MSG_ENTITY 5
1203 sizebuf_t *WriteDest (void)
1209 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1213 return &sv.datagram;
1216 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1217 entnum = PRVM_NUM_FOR_EDICT(ent);
1218 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1220 VM_Warning ("WriteDest: tried to write to non-client\n");
1221 return &sv.reliable_datagram;
1224 return &svs.clients[entnum-1].netconnection->message;
1227 VM_Warning ("WriteDest: bad destination\n");
1229 return &sv.reliable_datagram;
1235 return sv.writeentitiestoclient_msg;
1241 static void VM_SV_WriteByte (void)
1243 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1244 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1247 static void VM_SV_WriteChar (void)
1249 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1250 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1253 static void VM_SV_WriteShort (void)
1255 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1256 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1259 static void VM_SV_WriteLong (void)
1261 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1262 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1265 static void VM_SV_WriteAngle (void)
1267 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1268 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1271 static void VM_SV_WriteCoord (void)
1273 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1274 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1277 static void VM_SV_WriteString (void)
1279 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1280 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1283 static void VM_SV_WriteUnterminatedString (void)
1285 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1286 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1290 static void VM_SV_WriteEntity (void)
1292 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1293 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1296 //////////////////////////////////////////////////////////
1298 static void VM_SV_makestatic (void)
1303 // allow 0 parameters due to an id1 qc bug in which this function is used
1304 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1305 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1307 if (prog->argc >= 1)
1308 ent = PRVM_G_EDICT(OFS_PARM0);
1310 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1311 if (ent == prog->edicts)
1313 VM_Warning("makestatic: can not modify world entity\n");
1316 if (ent->priv.server->free)
1318 VM_Warning("makestatic: can not modify free entity\n");
1323 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1328 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1329 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1330 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1332 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1334 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1335 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1336 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1340 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1341 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1342 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1345 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1346 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1347 for (i=0 ; i<3 ; i++)
1349 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1350 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1353 // throw the entity away now
1357 //=============================================================================
1364 static void VM_SV_setspawnparms (void)
1370 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1372 ent = PRVM_G_EDICT(OFS_PARM0);
1373 i = PRVM_NUM_FOR_EDICT(ent);
1374 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1376 Con_Print("tried to setspawnparms on a non-client\n");
1380 // copy spawn parms out of the client_t
1381 client = svs.clients + i-1;
1382 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1383 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1390 Returns a color vector indicating the lighting at the requested point.
1392 (Internal Operation note: actually measures the light beneath the point, just like
1393 the model lighting on the client)
1398 static void VM_SV_getlight (void)
1400 vec3_t ambientcolor, diffusecolor, diffusenormal;
1402 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1403 p = PRVM_G_VECTOR(OFS_PARM0);
1404 VectorClear(ambientcolor);
1405 VectorClear(diffusecolor);
1406 VectorClear(diffusenormal);
1407 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1408 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1409 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1414 unsigned char type; // 1/2/8 or other value if isn't used
1418 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1419 static int vm_customstats_last;
1421 void VM_CustomStats_Clear (void)
1425 Z_Free(vm_customstats);
1426 vm_customstats = NULL;
1427 vm_customstats_last = -1;
1431 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1439 for(i=0; i<vm_customstats_last+1 ;i++)
1441 if(!vm_customstats[i].type)
1443 switch(vm_customstats[i].type)
1445 //string as 16 bytes
1448 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1449 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1450 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1451 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1452 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1454 //float field sent as-is
1456 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1458 //integer value of float field
1460 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1468 // void(float index, float type, .void field) SV_AddStat = #232;
1469 // Set up an auto-sent player stat.
1470 // Client's get thier own fields sent to them. Index may not be less than 32.
1471 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1472 // 1: string (4 stats carrying a total of 16 charactures)
1473 // 2: float (one stat, float converted to an integer for transportation)
1474 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1475 static void VM_SV_AddStat (void)
1480 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1484 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1487 VM_Warning("PF_SV_AddStat: not enough memory\n");
1491 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1492 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1493 off = PRVM_G_INT (OFS_PARM2);
1498 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1501 if(i >= (MAX_CL_STATS-32))
1503 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1506 if(i > (MAX_CL_STATS-32-4) && type == 1)
1508 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1511 vm_customstats[i].type = type;
1512 vm_customstats[i].fieldoffset = off;
1513 if(vm_customstats_last < i)
1514 vm_customstats_last = i;
1521 copies data from one entity to another
1523 copyentity(src, dst)
1526 static void VM_SV_copyentity (void)
1528 prvm_edict_t *in, *out;
1529 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1530 in = PRVM_G_EDICT(OFS_PARM0);
1531 if (in == prog->edicts)
1533 VM_Warning("copyentity: can not read world entity\n");
1536 if (in->priv.server->free)
1538 VM_Warning("copyentity: can not read free entity\n");
1541 out = PRVM_G_EDICT(OFS_PARM1);
1542 if (out == prog->edicts)
1544 VM_Warning("copyentity: can not modify world entity\n");
1547 if (out->priv.server->free)
1549 VM_Warning("copyentity: can not modify free entity\n");
1552 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1553 SV_LinkEdict(out, false);
1561 sets the color of a client and broadcasts the update to all connected clients
1563 setcolor(clientent, value)
1566 static void VM_SV_setcolor (void)
1572 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1573 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1574 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1576 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1578 Con_Print("tried to setcolor a non-client\n");
1582 client = svs.clients + entnum-1;
1585 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1587 client->edict->fields.server->team = (i & 15) + 1;
1590 if (client->old_colors != client->colors)
1592 client->old_colors = client->colors;
1593 // send notification to all clients
1594 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1595 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1596 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1604 effect(origin, modelname, startframe, framecount, framerate)
1607 static void VM_SV_effect (void)
1611 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1612 s = PRVM_G_STRING(OFS_PARM1);
1615 VM_Warning("effect: no model specified\n");
1619 i = SV_ModelIndex(s, 1);
1622 VM_Warning("effect: model not precached\n");
1626 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1628 VM_Warning("effect: framecount < 1\n");
1632 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1634 VM_Warning("effect: framerate < 1\n");
1638 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));
1641 static void VM_SV_te_blood (void)
1643 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1644 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1646 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1647 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1651 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1653 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1654 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1655 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1657 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1658 SV_FlushBroadcastMessages();
1661 static void VM_SV_te_bloodshower (void)
1663 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1664 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1666 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1667 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1677 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1679 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1680 SV_FlushBroadcastMessages();
1683 static void VM_SV_te_explosionrgb (void)
1685 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1686 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1687 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1689 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1690 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1691 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1693 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1694 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1695 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1696 SV_FlushBroadcastMessages();
1699 static void VM_SV_te_particlecube (void)
1701 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1702 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1704 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1705 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1708 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1709 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1719 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1721 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1722 // gravity true/false
1723 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1726 SV_FlushBroadcastMessages();
1729 static void VM_SV_te_particlerain (void)
1731 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1732 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1734 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1735 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1741 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1742 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1743 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1745 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1746 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1747 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1749 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1751 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1752 SV_FlushBroadcastMessages();
1755 static void VM_SV_te_particlesnow (void)
1757 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1758 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1760 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1761 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1763 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1764 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1771 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1772 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1773 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1775 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1777 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1778 SV_FlushBroadcastMessages();
1781 static void VM_SV_te_spark (void)
1783 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1784 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1786 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1787 MSG_WriteByte(&sv.datagram, TE_SPARK);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1793 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1794 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1795 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1797 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1798 SV_FlushBroadcastMessages();
1801 static void VM_SV_te_gunshotquad (void)
1803 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1804 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1805 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1810 SV_FlushBroadcastMessages();
1813 static void VM_SV_te_spikequad (void)
1815 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1816 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1817 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1822 SV_FlushBroadcastMessages();
1825 static void VM_SV_te_superspikequad (void)
1827 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1828 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1829 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1834 SV_FlushBroadcastMessages();
1837 static void VM_SV_te_explosionquad (void)
1839 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1840 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1841 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1845 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1846 SV_FlushBroadcastMessages();
1849 static void VM_SV_te_smallflash (void)
1851 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1852 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1853 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1858 SV_FlushBroadcastMessages();
1861 static void VM_SV_te_customflash (void)
1863 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1864 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1866 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1867 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1873 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1875 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1877 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1878 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1879 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1880 SV_FlushBroadcastMessages();
1883 static void VM_SV_te_gunshot (void)
1885 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1886 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1887 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1892 SV_FlushBroadcastMessages();
1895 static void VM_SV_te_spike (void)
1897 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1898 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1899 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1904 SV_FlushBroadcastMessages();
1907 static void VM_SV_te_superspike (void)
1909 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1910 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1911 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1915 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1916 SV_FlushBroadcastMessages();
1919 static void VM_SV_te_explosion (void)
1921 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1922 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1923 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1928 SV_FlushBroadcastMessages();
1931 static void VM_SV_te_tarexplosion (void)
1933 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1934 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1935 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1940 SV_FlushBroadcastMessages();
1943 static void VM_SV_te_wizspike (void)
1945 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1946 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1947 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1952 SV_FlushBroadcastMessages();
1955 static void VM_SV_te_knightspike (void)
1957 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1958 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1959 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1964 SV_FlushBroadcastMessages();
1967 static void VM_SV_te_lavasplash (void)
1969 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1970 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1971 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1976 SV_FlushBroadcastMessages();
1979 static void VM_SV_te_teleport (void)
1981 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1982 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1983 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1988 SV_FlushBroadcastMessages();
1991 static void VM_SV_te_explosion2 (void)
1993 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1994 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1995 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2001 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2002 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2003 SV_FlushBroadcastMessages();
2006 static void VM_SV_te_lightning1 (void)
2008 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2009 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2010 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2012 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2014 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2020 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2021 SV_FlushBroadcastMessages();
2024 static void VM_SV_te_lightning2 (void)
2026 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2027 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2028 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2030 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2033 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2034 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2036 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2037 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2038 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2039 SV_FlushBroadcastMessages();
2042 static void VM_SV_te_lightning3 (void)
2044 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2045 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2046 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2048 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2050 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2051 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2055 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2057 SV_FlushBroadcastMessages();
2060 static void VM_SV_te_beam (void)
2062 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2063 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2064 MSG_WriteByte(&sv.datagram, TE_BEAM);
2066 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2069 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2070 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2072 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2073 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2074 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2075 SV_FlushBroadcastMessages();
2078 static void VM_SV_te_plasmaburn (void)
2080 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2081 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2082 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2083 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2084 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2085 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2086 SV_FlushBroadcastMessages();
2089 static void VM_SV_te_flamejet (void)
2091 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2092 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2093 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2095 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2096 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2101 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2103 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2104 SV_FlushBroadcastMessages();
2107 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2110 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2112 bestdist = 1000000000;
2114 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2116 // clip original point to each triangle of the surface and find the
2117 // triangle that is closest
2118 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2119 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2120 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2121 TriangleNormal(v[0], v[1], v[2], facenormal);
2122 VectorNormalize(facenormal);
2123 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2124 VectorMA(p, offsetdist, facenormal, temp);
2125 for (j = 0, k = 2;j < 3;k = j, j++)
2127 VectorSubtract(v[k], v[j], edgenormal);
2128 CrossProduct(edgenormal, facenormal, sidenormal);
2129 VectorNormalize(sidenormal);
2130 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2132 VectorMA(temp, offsetdist, sidenormal, temp);
2134 dist = VectorDistance2(temp, p);
2135 if (bestdist > dist)
2138 VectorCopy(temp, out);
2143 static model_t *getmodel(prvm_edict_t *ed)
2146 if (!ed || ed->priv.server->free)
2148 modelindex = (int)ed->fields.server->modelindex;
2149 if (modelindex < 1 || modelindex >= MAX_MODELS)
2151 return sv.models[modelindex];
2154 static msurface_t *getsurface(model_t *model, int surfacenum)
2156 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2158 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2162 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2163 static void VM_SV_getsurfacenumpoints(void)
2166 msurface_t *surface;
2167 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2168 // return 0 if no such surface
2169 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2171 PRVM_G_FLOAT(OFS_RETURN) = 0;
2175 // note: this (incorrectly) assumes it is a simple polygon
2176 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2178 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2179 static void VM_SV_getsurfacepoint(void)
2183 msurface_t *surface;
2185 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2186 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2187 ed = PRVM_G_EDICT(OFS_PARM0);
2188 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2190 // note: this (incorrectly) assumes it is a simple polygon
2191 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2192 if (pointnum < 0 || pointnum >= surface->num_vertices)
2194 // FIXME: implement rotation/scaling
2195 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2197 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2198 // float SPA_POSITION = 0;
2199 // float SPA_S_AXIS = 1;
2200 // float SPA_T_AXIS = 2;
2201 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2202 // float SPA_TEXCOORDS0 = 4;
2203 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2204 // float SPA_LIGHTMAP0_COLOR = 6;
2205 static void VM_SV_getsurfacepointattribute(void)
2209 msurface_t *surface;
2213 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2214 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2215 ed = PRVM_G_EDICT(OFS_PARM0);
2216 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2218 // note: this (incorrectly) assumes it is a simple polygon
2219 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2220 if (pointnum < 0 || pointnum >= surface->num_vertices)
2222 // FIXME: implement rotation/scaling
2223 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2225 switch( attributetype ) {
2226 // float SPA_POSITION = 0;
2228 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2230 // float SPA_S_AXIS = 1;
2232 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2234 // float SPA_T_AXIS = 2;
2236 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2238 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2240 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2242 // float SPA_TEXCOORDS0 = 4;
2244 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2245 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2246 ret[0] = texcoord[0];
2247 ret[1] = texcoord[1];
2251 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2253 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2254 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2255 ret[0] = texcoord[0];
2256 ret[1] = texcoord[1];
2260 // float SPA_LIGHTMAP0_COLOR = 6;
2262 // ignore alpha for now..
2263 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2266 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2270 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2271 static void VM_SV_getsurfacenormal(void)
2274 msurface_t *surface;
2276 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2277 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2278 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2280 // FIXME: implement rotation/scaling
2281 // note: this (incorrectly) assumes it is a simple polygon
2282 // note: this only returns the first triangle, so it doesn't work very
2283 // well for curved surfaces or arbitrary meshes
2284 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);
2285 VectorNormalize(normal);
2286 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2288 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2289 static void VM_SV_getsurfacetexture(void)
2292 msurface_t *surface;
2293 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2294 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2295 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2297 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2299 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2300 static void VM_SV_getsurfacenearpoint(void)
2302 int surfacenum, best;
2304 vec_t dist, bestdist;
2307 msurface_t *surface;
2309 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2310 PRVM_G_FLOAT(OFS_RETURN) = -1;
2311 ed = PRVM_G_EDICT(OFS_PARM0);
2312 point = PRVM_G_VECTOR(OFS_PARM1);
2314 if (!ed || ed->priv.server->free)
2316 model = getmodel(ed);
2317 if (!model || !model->num_surfaces)
2320 // FIXME: implement rotation/scaling
2321 VectorSubtract(point, ed->fields.server->origin, p);
2323 bestdist = 1000000000;
2324 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2326 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2327 // first see if the nearest point on the surface's box is closer than the previous match
2328 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2329 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2330 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2331 dist = VectorLength2(clipped);
2332 if (dist < bestdist)
2334 // it is, check the nearest point on the actual geometry
2335 clippointtosurface(model, surface, p, clipped);
2336 VectorSubtract(clipped, p, clipped);
2337 dist += VectorLength2(clipped);
2338 if (dist < bestdist)
2340 // that's closer too, store it as the best match
2346 PRVM_G_FLOAT(OFS_RETURN) = best;
2348 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2349 static void VM_SV_getsurfaceclippedpoint(void)
2353 msurface_t *surface;
2355 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2356 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2357 ed = PRVM_G_EDICT(OFS_PARM0);
2358 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2360 // FIXME: implement rotation/scaling
2361 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2362 clippointtosurface(model, surface, p, out);
2363 // FIXME: implement rotation/scaling
2364 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2367 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2368 //this function originally written by KrimZon, made shorter by LordHavoc
2369 static void VM_SV_clientcommand (void)
2371 client_t *temp_client;
2373 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2375 //find client for this entity
2376 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2377 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2379 Con_Print("PF_clientcommand: entity is not a client\n");
2383 temp_client = host_client;
2384 host_client = svs.clients + i;
2385 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2386 host_client = temp_client;
2389 //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)
2390 static void VM_SV_setattachment (void)
2392 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2393 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2394 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2398 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2400 if (e == prog->edicts)
2402 VM_Warning("setattachment: can not modify world entity\n");
2405 if (e->priv.server->free)
2407 VM_Warning("setattachment: can not modify free entity\n");
2411 if (tagentity == NULL)
2412 tagentity = prog->edicts;
2414 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2416 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2418 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2421 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2423 modelindex = (int)tagentity->fields.server->modelindex;
2424 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2426 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2428 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);
2431 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));
2435 /////////////////////////////////////////
2436 // DP_MD3_TAGINFO extension coded by VorteX
2438 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2443 i = (int)e->fields.server->modelindex;
2444 if (i < 1 || i >= MAX_MODELS)
2446 model = sv.models[i];
2448 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2451 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2453 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2457 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);
2459 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);
2462 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2468 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2469 && (model = sv.models[(int)ent->fields.server->modelindex])
2470 && model->animscenes)
2472 // if model has wrong frame, engine automatically switches to model first frame
2473 frame = (int)ent->fields.server->frame;
2474 if (frame < 0 || frame >= model->numframes)
2476 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2478 *out = identitymatrix;
2482 // Warnings/errors code:
2483 // 0 - normal (everything all-right)
2486 // 3 - null or non-precached model
2487 // 4 - no tags with requested index
2488 // 5 - runaway loop at attachment chain
2489 extern cvar_t cl_bob;
2490 extern cvar_t cl_bobcycle;
2491 extern cvar_t cl_bobup;
2492 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2496 int modelindex, attachloop;
2497 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2500 *out = identitymatrix; // warnings and errors return identical matrix
2502 if (ent == prog->edicts)
2504 if (ent->priv.server->free)
2507 modelindex = (int)ent->fields.server->modelindex;
2508 if (modelindex <= 0 || modelindex > MAX_MODELS)
2511 model = sv.models[modelindex];
2513 tagmatrix = identitymatrix;
2514 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2518 if (attachloop >= 256) // prevent runaway looping
2520 // apply transformation by child's tagindex on parent entity and then
2521 // by parent entity itself
2522 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2523 if (ret && attachloop == 0)
2525 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2526 SV_GetEntityMatrix(ent, &entitymatrix, false);
2527 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2528 // next iteration we process the parent entity
2529 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2531 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2532 ent = PRVM_EDICT_NUM(val->edict);
2539 // RENDER_VIEWMODEL magic
2540 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2542 Matrix4x4_Copy(&tagmatrix, out);
2543 ent = PRVM_EDICT_NUM(val->edict);
2545 SV_GetEntityMatrix(ent, &entitymatrix, true);
2546 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2549 // Cl_bob, ported from rendering code
2550 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2553 // LordHavoc: this code is *weird*, but not replacable (I think it
2554 // should be done in QC on the server, but oh well, quake is quake)
2555 // LordHavoc: figured out bobup: the time at which the sin is at 180
2556 // degrees (which allows lengthening or squishing the peak or valley)
2557 cycle = sv.time/cl_bobcycle.value;
2558 cycle -= (int)cycle;
2559 if (cycle < cl_bobup.value)
2560 cycle = sin(M_PI * cycle / cl_bobup.value);
2562 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2563 // bob is proportional to velocity in the xy plane
2564 // (don't count Z, or jumping messes it up)
2565 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;
2566 bob = bob*0.3 + bob*0.7*cycle;
2567 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2574 //float(entity ent, string tagname) gettagindex;
2576 static void VM_SV_gettagindex (void)
2579 const char *tag_name;
2580 int modelindex, tag_index;
2582 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2584 ent = PRVM_G_EDICT(OFS_PARM0);
2585 tag_name = PRVM_G_STRING(OFS_PARM1);
2587 if (ent == prog->edicts)
2589 VM_Warning("gettagindex: can't affect world entity\n");
2592 if (ent->priv.server->free)
2594 VM_Warning("gettagindex: can't affect free entity\n");
2598 modelindex = (int)ent->fields.server->modelindex;
2600 if (modelindex <= 0 || modelindex > MAX_MODELS)
2601 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2604 tag_index = SV_GetTagIndex(ent, tag_name);
2606 if(developer.integer >= 100)
2607 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2609 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2612 //vector(entity ent, float tagindex) gettaginfo;
2613 static void VM_SV_gettaginfo (void)
2617 matrix4x4_t tag_matrix;
2620 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2622 e = PRVM_G_EDICT(OFS_PARM0);
2623 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2625 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2626 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2631 VM_Warning("gettagindex: can't affect world entity\n");
2634 VM_Warning("gettagindex: can't affect free entity\n");
2637 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2640 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2643 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2648 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2649 static void VM_SV_dropclient (void)
2652 client_t *oldhostclient;
2653 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2654 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2655 if (clientnum < 0 || clientnum >= svs.maxclients)
2657 VM_Warning("dropclient: not a client\n");
2660 if (!svs.clients[clientnum].active)
2662 VM_Warning("dropclient: that client slot is not connected\n");
2665 oldhostclient = host_client;
2666 host_client = svs.clients + clientnum;
2667 SV_DropClient(false);
2668 host_client = oldhostclient;
2671 //entity() spawnclient (DP_SV_BOTCLIENT)
2672 static void VM_SV_spawnclient (void)
2676 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2677 prog->xfunction->builtinsprofile += 2;
2679 for (i = 0;i < svs.maxclients;i++)
2681 if (!svs.clients[i].active)
2683 prog->xfunction->builtinsprofile += 100;
2684 SV_ConnectClient (i, NULL);
2685 // this has to be set or else ClientDisconnect won't be called
2686 // we assume the qc will call ClientConnect...
2687 svs.clients[i].clientconnectcalled = true;
2688 ed = PRVM_EDICT_NUM(i + 1);
2692 VM_RETURN_EDICT(ed);
2695 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2696 static void VM_SV_clienttype (void)
2699 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2700 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2701 if (clientnum < 0 || clientnum >= svs.maxclients)
2702 PRVM_G_FLOAT(OFS_RETURN) = 3;
2703 else if (!svs.clients[clientnum].active)
2704 PRVM_G_FLOAT(OFS_RETURN) = 0;
2705 else if (svs.clients[clientnum].netconnection)
2706 PRVM_G_FLOAT(OFS_RETURN) = 1;
2708 PRVM_G_FLOAT(OFS_RETURN) = 2;
2715 string(string key) serverkey
2718 void VM_SV_serverkey(void)
2720 char string[VM_STRINGTEMP_LENGTH];
2721 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2722 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2723 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2726 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2727 static void VM_SV_setmodelindex (void)
2732 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2734 e = PRVM_G_EDICT(OFS_PARM0);
2735 if (e == prog->edicts)
2737 VM_Warning("setmodelindex: can not modify world entity\n");
2740 if (e->priv.server->free)
2742 VM_Warning("setmodelindex: can not modify free entity\n");
2745 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2746 if (i <= 0 || i > MAX_MODELS)
2748 VM_Warning("setmodelindex: invalid modelindex\n");
2751 if (!sv.model_precache[i][0])
2753 VM_Warning("setmodelindex: model not precached\n");
2757 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2758 e->fields.server->modelindex = i;
2764 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2765 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2767 SetMinMaxSize (e, quakemins, quakemaxs, true);
2770 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2773 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2774 static void VM_SV_modelnameforindex (void)
2777 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2779 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2781 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2782 if (i <= 0 || i > MAX_MODELS)
2784 VM_Warning("modelnameforindex: invalid modelindex\n");
2787 if (!sv.model_precache[i][0])
2789 VM_Warning("modelnameforindex: model not precached\n");
2793 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2796 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2797 static void VM_SV_particleeffectnum (void)
2800 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2801 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2804 PRVM_G_FLOAT(OFS_RETURN) = i;
2807 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2808 static void VM_SV_trailparticles (void)
2810 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2812 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2813 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2814 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2815 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2816 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2817 SV_FlushBroadcastMessages();
2820 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2821 static void VM_SV_pointparticles (void)
2823 int effectnum, count;
2825 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2826 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2827 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2828 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2829 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2830 if (count == 1 && !VectorLength2(vel))
2833 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2834 MSG_WriteShort(&sv.datagram, effectnum);
2835 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2839 // 1+2+12+12+2=29 bytes
2840 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2841 MSG_WriteShort(&sv.datagram, effectnum);
2842 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2843 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2844 MSG_WriteShort(&sv.datagram, count);
2847 SV_FlushBroadcastMessages();
2850 prvm_builtin_t vm_sv_builtins[] = {
2851 NULL, // #0 NULL function (not callable) (QUAKE)
2852 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2853 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2854 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2855 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2856 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2857 VM_break, // #6 void() break (QUAKE)
2858 VM_random, // #7 float() random (QUAKE)
2859 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2860 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2861 VM_error, // #10 void(string e) error (QUAKE)
2862 VM_objerror, // #11 void(string e) objerror (QUAKE)
2863 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2864 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2865 VM_spawn, // #14 entity() spawn (QUAKE)
2866 VM_remove, // #15 void(entity e) remove (QUAKE)
2867 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2868 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2869 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2870 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2871 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2872 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2873 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2874 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2875 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2876 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2877 VM_ftos, // #26 string(float f) ftos (QUAKE)
2878 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2879 VM_coredump, // #28 void() coredump (QUAKE)
2880 VM_traceon, // #29 void() traceon (QUAKE)
2881 VM_traceoff, // #30 void() traceoff (QUAKE)
2882 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2883 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2884 NULL, // #33 (QUAKE)
2885 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2886 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2887 VM_rint, // #36 float(float v) rint (QUAKE)
2888 VM_floor, // #37 float(float v) floor (QUAKE)
2889 VM_ceil, // #38 float(float v) ceil (QUAKE)
2890 NULL, // #39 (QUAKE)
2891 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2892 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2893 NULL, // #42 (QUAKE)
2894 VM_fabs, // #43 float(float f) fabs (QUAKE)
2895 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2896 VM_cvar, // #45 float(string s) cvar (QUAKE)
2897 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2898 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2899 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2900 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2901 NULL, // #50 (QUAKE)
2902 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2903 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2904 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2905 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2906 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2907 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2908 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2909 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2910 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2911 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2912 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2913 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2914 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2915 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2916 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2917 NULL, // #66 (QUAKE)
2918 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2919 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2920 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2921 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2922 NULL, // #71 (QUAKE)
2923 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2924 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2925 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2926 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2927 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2928 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2929 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2930 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2931 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2932 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2933 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2934 NULL, // #83 (QUAKE)
2935 NULL, // #84 (QUAKE)
2936 NULL, // #85 (QUAKE)
2937 NULL, // #86 (QUAKE)
2938 NULL, // #87 (QUAKE)
2939 NULL, // #88 (QUAKE)
2940 NULL, // #89 (QUAKE)
2941 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2942 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2943 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2944 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2945 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2946 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2947 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2948 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2949 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2950 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2951 // FrikaC and Telejano range #100-#199
2962 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2963 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2964 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2965 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2966 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2967 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2968 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2969 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2970 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2971 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3052 // FTEQW range #200-#299
3071 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3074 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3075 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3076 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3077 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3078 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3079 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3080 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3081 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3082 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3083 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3085 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3153 // CSQC range #300-#399
3154 NULL, // #300 void() clearscene (EXT_CSQC)
3155 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3156 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3157 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3158 NULL, // #304 void() renderscene (EXT_CSQC)
3159 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3160 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3161 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3162 NULL, // #308 void() R_EndPolygon
3164 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3165 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3169 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3170 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3171 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3172 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3173 NULL, // #319 void(string name) freepic (EXT_CSQC)
3174 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3175 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3176 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3177 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3178 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3179 NULL, // #325 void(void) drawresetcliparea
3184 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3185 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3186 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3187 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3188 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3189 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3190 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3191 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3192 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3193 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3194 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3195 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3196 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3197 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3198 NULL, // #344 vector() getmousepos (EXT_CSQC)
3199 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3200 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3201 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3202 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3203 NULL, // #349 float() isdemo (EXT_CSQC)
3204 VM_isserver, // #350 float() isserver (EXT_CSQC)
3205 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3206 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3207 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3208 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3214 NULL, // #360 float() readbyte (EXT_CSQC)
3215 NULL, // #361 float() readchar (EXT_CSQC)
3216 NULL, // #362 float() readshort (EXT_CSQC)
3217 NULL, // #363 float() readlong (EXT_CSQC)
3218 NULL, // #364 float() readcoord (EXT_CSQC)
3219 NULL, // #365 float() readangle (EXT_CSQC)
3220 NULL, // #366 string() readstring (EXT_CSQC)
3221 NULL, // #367 float() readfloat (EXT_CSQC)
3254 // LordHavoc's range #400-#499
3255 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3256 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3257 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3258 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3259 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3260 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3261 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3262 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3263 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)
3264 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3265 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3266 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3267 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3268 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3269 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3270 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3271 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3272 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3273 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3274 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3275 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3276 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3277 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3278 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3279 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3280 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3281 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3282 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3283 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3284 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3285 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3286 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3287 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3288 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3289 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3290 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3291 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3292 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3293 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3294 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3295 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3296 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3297 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3298 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3299 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3300 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3301 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3302 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3303 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3304 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3305 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3306 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3307 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3308 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3309 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3310 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3311 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3312 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3314 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3315 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3316 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3317 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3318 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3319 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3320 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3321 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3322 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3323 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3324 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3326 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3327 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3328 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3329 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3330 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3331 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3332 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3333 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3334 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3335 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3336 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3337 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3338 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3339 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3340 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3341 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3349 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3350 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3365 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3366 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3367 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3377 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3379 void VM_SV_Cmd_Init(void)
3384 void VM_SV_Cmd_Reset(void)
3386 if(prog->funcoffsets.SV_Shutdown)
3388 func_t s = prog->funcoffsets.SV_Shutdown;
3389 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3390 PRVM_ExecuteProgram(s,"SV_Shutdown() required");