6 //============================================================================
11 const char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
23 "DP_CSQC_ENTITYNOCULL "
24 "DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET "
25 "DP_CSQC_MULTIFRAME_INTERPOLATION "
26 "DP_CSQC_BOXPARTICLES "
27 "DP_CSQC_SPAWNPARTICLE "
28 "DP_CSQC_QUERYRENDERENTITY "
41 "DP_EF_RESTARTANIM_BIT "
46 "DP_ENT_CUSTOMCOLORMAP "
47 "DP_ENT_EXTERIORMODELTOCLIENT "
50 "DP_ENT_LOWPRECISION "
54 "DP_GFX_EXTERNALTEXTURES "
55 "DP_GFX_EXTERNALTEXTURES_PERMAP "
57 "DP_GFX_MODEL_INTERPOLATION "
58 "DP_GFX_QUAKE3MODELTAGS "
62 "DP_GFX_FONTS_FREETYPE "
64 "DP_FONT_VARIABLEWIDTH "
66 "DP_HALFLIFE_MAP_CVAR "
69 "DP_LIGHTSTYLE_STATICVALUE "
73 "DP_MOVETYPEBOUNCEMISSILE "
76 "DP_QC_ASINACOSATANATAN2TAN "
82 "DP_QC_CVAR_DEFSTRING "
83 "DP_QC_CVAR_DESCRIPTION "
90 "DP_QC_EXTRESPONSEPACKET "
92 "DP_QC_FINDCHAINFLAGS "
93 "DP_QC_FINDCHAINFLOAT "
94 "DP_QC_FINDCHAIN_TOFIELD "
100 "DP_QC_GETSURFACETRIANGLE "
101 "DP_QC_GETSURFACEPOINTATTRIBUTE "
103 "DP_QC_GETTAGINFO_BONEPROPERTIES "
105 "DP_QC_GETTIME_CDTRACK "
108 "DP_QC_MULTIPLETEMPSTRINGS "
109 "DP_QC_NUM_FOR_EDICT "
111 "DP_QC_SINCOSSQRTPOW "
114 "DP_QC_STRINGBUFFERS "
115 "DP_QC_STRINGBUFFERS_CVARLIST "
116 "DP_QC_STRINGCOLORFUNCTIONS "
117 "DP_QC_STRING_CASE_FUNCTIONS "
119 "DP_QC_TOKENIZEBYSEPARATOR "
120 "DP_QC_TOKENIZE_CONSOLE "
123 "DP_QC_TRACE_MOVETYPE_HITMODEL "
124 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
125 "DP_QC_UNLIMITEDTEMPSTRINGS "
128 "DP_QC_VECTOANGLES_WITH_ROLL "
129 "DP_QC_VECTORVECTORS "
136 "DP_SKELETONOBJECTS "
137 "DP_SND_DIRECTIONLESSATTNNONE "
142 "DP_SND_GETSOUNDTIME "
144 "DP_VIDEO_SUBTITLES "
148 "DP_SV_BOUNCEFACTOR "
149 "DP_SV_CLIENTCAMERA "
150 "DP_SV_CLIENTCOLORS "
153 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
154 "DP_SV_DISCARDABLEDEMO "
155 "DP_SV_DRAWONLYTOCLIENT "
158 "DP_SV_ENTITYCONTENTSTRANSITION "
159 "DP_SV_MODELFLAGS_AS_EFFECTS "
160 "DP_SV_MOVETYPESTEP_LANDEVENT "
162 "DP_SV_NODRAWTOCLIENT "
163 "DP_SV_ONENTITYNOSPAWNFUNCTION "
164 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
166 "DP_SV_PING_PACKETLOSS "
167 "DP_SV_PLAYERPHYSICS "
168 "DP_SV_POINTPARTICLES "
170 "DP_SV_PRECACHEANYTIME "
174 "DP_SV_ROTATINGBMODEL "
178 "DP_SV_SPAWNFUNC_PREFIX "
179 "DP_SV_WRITEPICTURE "
180 "DP_SV_WRITEUNTERMINATEDSTRING "
184 "DP_TE_EXPLOSIONRGB "
186 "DP_TE_PARTICLECUBE "
187 "DP_TE_PARTICLERAIN "
188 "DP_TE_PARTICLESNOW "
190 "DP_TE_QUADEFFECTS1 "
193 "DP_TE_STANDARDEFFECTBUILTINS "
194 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
198 "FTE_CSQC_SKELETONOBJECTS "
201 "KRIMZON_SV_PARSECLIENTCOMMAND "
204 "NEXUIZ_PLAYERMODEL "
206 "PRYDON_CLIENTCURSOR "
207 "TENEBRAE_GFX_DLIGHTS "
210 //"EXT_CSQC " // not ready yet
217 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.
219 setorigin (entity, origin)
222 static void VM_SV_setorigin (void)
227 VM_SAFEPARMCOUNT(2, VM_setorigin);
229 e = PRVM_G_EDICT(OFS_PARM0);
230 if (e == prog->edicts)
232 VM_Warning("setorigin: can not modify world entity\n");
235 if (e->priv.server->free)
237 VM_Warning("setorigin: can not modify free entity\n");
240 org = PRVM_G_VECTOR(OFS_PARM1);
241 VectorCopy (org, e->fields.server->origin);
245 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
246 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
250 for (i=0 ; i<3 ; i++)
252 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
254 // set derived values
255 VectorCopy (min, e->fields.server->mins);
256 VectorCopy (max, e->fields.server->maxs);
257 VectorSubtract (max, min, e->fields.server->size);
266 the size box is rotated by the current angle
267 LordHavoc: no it isn't...
269 setsize (entity, minvector, maxvector)
272 static void VM_SV_setsize (void)
277 VM_SAFEPARMCOUNT(3, VM_setsize);
279 e = PRVM_G_EDICT(OFS_PARM0);
280 if (e == prog->edicts)
282 VM_Warning("setsize: can not modify world entity\n");
285 if (e->priv.server->free)
287 VM_Warning("setsize: can not modify free entity\n");
290 min = PRVM_G_VECTOR(OFS_PARM1);
291 max = PRVM_G_VECTOR(OFS_PARM2);
292 SetMinMaxSize (e, min, max, false);
300 setmodel(entity, model)
303 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
304 static void VM_SV_setmodel (void)
310 VM_SAFEPARMCOUNT(2, VM_setmodel);
312 e = PRVM_G_EDICT(OFS_PARM0);
313 if (e == prog->edicts)
315 VM_Warning("setmodel: can not modify world entity\n");
318 if (e->priv.server->free)
320 VM_Warning("setmodel: can not modify free entity\n");
323 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
324 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
325 e->fields.server->modelindex = i;
327 mod = SV_GetModelByIndex(i);
331 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
332 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
334 SetMinMaxSize (e, quakemins, quakemaxs, true);
337 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
344 single print to a specific client
346 sprint(clientent, value)
349 static void VM_SV_sprint (void)
353 char string[VM_STRINGTEMP_LENGTH];
355 VM_VarString(1, string, sizeof(string));
357 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
359 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
360 // LordHavoc: div0 requested that sprintto world operate like print
367 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
369 VM_Warning("tried to centerprint to a non-client\n");
373 client = svs.clients + entnum-1;
374 if (!client->netconnection)
377 MSG_WriteChar(&client->netconnection->message,svc_print);
378 MSG_WriteString(&client->netconnection->message, string);
386 single print to a specific client
388 centerprint(clientent, value)
391 static void VM_SV_centerprint (void)
395 char string[VM_STRINGTEMP_LENGTH];
397 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
399 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
401 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
403 VM_Warning("tried to centerprint to a non-client\n");
407 client = svs.clients + entnum-1;
408 if (!client->netconnection)
411 VM_VarString(1, string, sizeof(string));
412 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
413 MSG_WriteString(&client->netconnection->message, string);
420 particle(origin, color, count)
423 static void VM_SV_particle (void)
429 VM_SAFEPARMCOUNT(4, VM_SV_particle);
431 org = PRVM_G_VECTOR(OFS_PARM0);
432 dir = PRVM_G_VECTOR(OFS_PARM1);
433 color = PRVM_G_FLOAT(OFS_PARM2);
434 count = PRVM_G_FLOAT(OFS_PARM3);
435 SV_StartParticle (org, dir, (int)color, (int)count);
445 static void VM_SV_ambientsound (void)
449 float vol, attenuation;
452 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
454 pos = PRVM_G_VECTOR (OFS_PARM0);
455 samp = PRVM_G_STRING(OFS_PARM1);
456 vol = PRVM_G_FLOAT(OFS_PARM2);
457 attenuation = PRVM_G_FLOAT(OFS_PARM3);
459 // check to see if samp was properly precached
460 soundnum = SV_SoundIndex(samp, 1);
468 // add an svc_spawnambient command to the level signon packet
471 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
473 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
475 MSG_WriteVector(&sv.signon, pos, sv.protocol);
477 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
478 MSG_WriteShort (&sv.signon, soundnum);
480 MSG_WriteByte (&sv.signon, soundnum);
482 MSG_WriteByte (&sv.signon, (int)(vol*255));
483 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
491 Each entity can have eight independant sound sources, like voice,
494 Channel 0 is an auto-allocate channel, the others override anything
495 already running on that entity/channel pair.
497 An attenuation of 0 will play full volume everywhere in the level.
498 Larger attenuations will drop off.
502 static void VM_SV_sound (void)
506 prvm_edict_t *entity;
510 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
512 entity = PRVM_G_EDICT(OFS_PARM0);
513 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
514 sample = PRVM_G_STRING(OFS_PARM2);
515 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
516 attenuation = PRVM_G_FLOAT(OFS_PARM4);
519 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
523 if (volume < 0 || volume > 255)
525 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
529 if (attenuation < 0 || attenuation > 4)
531 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
535 if (channel < 0 || channel > 7)
537 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
541 SV_StartSound (entity, channel, sample, volume, attenuation);
548 Follows the same logic as VM_SV_sound, except instead of
549 an entity, an origin for the sound is provided, and channel
550 is omitted (since no entity is being tracked).
554 static void VM_SV_pointsound(void)
561 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
563 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
564 sample = PRVM_G_STRING(OFS_PARM1);
565 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
566 attenuation = PRVM_G_FLOAT(OFS_PARM3);
568 if (volume < 0 || volume > 255)
570 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
574 if (attenuation < 0 || attenuation > 4)
576 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
580 SV_StartPointSound (org, sample, volume, attenuation);
587 Used for use tracing and shot targeting
588 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
589 if the tryents flag is set.
591 traceline (vector1, vector2, movetype, ignore)
594 static void VM_SV_traceline (void)
601 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
603 prog->xfunction->builtinsprofile += 30;
605 v1 = PRVM_G_VECTOR(OFS_PARM0);
606 v2 = PRVM_G_VECTOR(OFS_PARM1);
607 move = (int)PRVM_G_FLOAT(OFS_PARM2);
608 ent = PRVM_G_EDICT(OFS_PARM3);
610 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
611 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));
613 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
615 VM_SetTraceGlobals(&trace);
623 Used for use tracing and shot targeting
624 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
625 if the tryents flag is set.
627 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
630 // LordHavoc: added this for my own use, VERY useful, similar to traceline
631 static void VM_SV_tracebox (void)
633 float *v1, *v2, *m1, *m2;
638 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
640 prog->xfunction->builtinsprofile += 30;
642 v1 = PRVM_G_VECTOR(OFS_PARM0);
643 m1 = PRVM_G_VECTOR(OFS_PARM1);
644 m2 = PRVM_G_VECTOR(OFS_PARM2);
645 v2 = PRVM_G_VECTOR(OFS_PARM3);
646 move = (int)PRVM_G_FLOAT(OFS_PARM4);
647 ent = PRVM_G_EDICT(OFS_PARM5);
649 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
650 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));
652 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
654 VM_SetTraceGlobals(&trace);
657 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
662 vec3_t original_origin;
663 vec3_t original_velocity;
664 vec3_t original_angles;
665 vec3_t original_avelocity;
669 VectorCopy(tossent->fields.server->origin , original_origin );
670 VectorCopy(tossent->fields.server->velocity , original_velocity );
671 VectorCopy(tossent->fields.server->angles , original_angles );
672 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
674 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
675 if (val != NULL && val->_float != 0)
676 gravity = val->_float;
679 gravity *= sv_gravity.value * 0.025;
681 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
683 SV_CheckVelocity (tossent);
684 tossent->fields.server->velocity[2] -= gravity;
685 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
686 VectorScale (tossent->fields.server->velocity, 0.05, move);
687 VectorAdd (tossent->fields.server->origin, move, end);
688 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
689 VectorCopy (trace.endpos, tossent->fields.server->origin);
690 tossent->fields.server->velocity[2] -= gravity;
692 if (trace.fraction < 1)
696 VectorCopy(original_origin , tossent->fields.server->origin );
697 VectorCopy(original_velocity , tossent->fields.server->velocity );
698 VectorCopy(original_angles , tossent->fields.server->angles );
699 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
704 static void VM_SV_tracetoss (void)
708 prvm_edict_t *ignore;
710 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
712 prog->xfunction->builtinsprofile += 600;
714 ent = PRVM_G_EDICT(OFS_PARM0);
715 if (ent == prog->edicts)
717 VM_Warning("tracetoss: can not use world entity\n");
720 ignore = PRVM_G_EDICT(OFS_PARM1);
722 trace = SV_Trace_Toss (ent, ignore);
724 VM_SetTraceGlobals(&trace);
727 //============================================================================
729 static int checkpvsbytes;
730 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
732 static int VM_SV_newcheckclient (int check)
738 // cycle to the next one
740 check = bound(1, check, svs.maxclients);
741 if (check == svs.maxclients)
749 prog->xfunction->builtinsprofile++;
751 if (i == svs.maxclients+1)
753 // look up the client's edict
754 ent = PRVM_EDICT_NUM(i);
755 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
756 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
758 // found a valid client (possibly the same one again)
762 // get the PVS for the entity
763 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
765 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
766 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
775 Returns a client (or object that has a client enemy) that would be a
778 If there is more than one valid option, they are cycled each frame
780 If (self.origin + self.viewofs) is not in the PVS of the current target,
781 it is not returned at all.
786 int c_invis, c_notvis;
787 static void VM_SV_checkclient (void)
789 prvm_edict_t *ent, *self;
792 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
794 // find a new check if on a new frame
795 if (sv.time - sv.lastchecktime >= 0.1)
797 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
798 sv.lastchecktime = sv.time;
801 // return check if it might be visible
802 ent = PRVM_EDICT_NUM(sv.lastcheck);
803 if (ent->priv.server->free || ent->fields.server->health <= 0)
805 VM_RETURN_EDICT(prog->edicts);
809 // if current entity can't possibly see the check entity, return 0
810 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
811 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
812 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
815 VM_RETURN_EDICT(prog->edicts);
819 // might be able to see it
821 VM_RETURN_EDICT(ent);
824 //============================================================================
830 Checks if an entity is in a point's PVS.
831 Should be fast but can be inexact.
833 float checkpvs(vector viewpos, entity viewee) = #240;
836 static void VM_SV_checkpvs (void)
839 prvm_edict_t *viewee;
844 unsigned char fatpvs[MAX_MAP_LEAFS/8];
847 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
848 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
849 viewee = PRVM_G_EDICT(OFS_PARM1);
851 if(viewee->priv.server->free)
853 VM_Warning("checkpvs: can not check free entity\n");
854 PRVM_G_FLOAT(OFS_RETURN) = 4;
859 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
861 // no PVS support on this worldmodel... darn
862 PRVM_G_FLOAT(OFS_RETURN) = 3;
865 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
868 // viewpos isn't in any PVS... darn
869 PRVM_G_FLOAT(OFS_RETURN) = 2;
872 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
874 // using fat PVS like FTEQW does (slow)
875 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
877 // no PVS support on this worldmodel... darn
878 PRVM_G_FLOAT(OFS_RETURN) = 3;
881 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
884 // viewpos isn't in any PVS... darn
885 PRVM_G_FLOAT(OFS_RETURN) = 2;
888 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
897 Sends text over to the client's execution buffer
899 stuffcmd (clientent, value, ...)
902 static void VM_SV_stuffcmd (void)
906 char string[VM_STRINGTEMP_LENGTH];
908 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
910 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
911 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
913 VM_Warning("Can't stuffcmd to a non-client\n");
917 VM_VarString(1, string, sizeof(string));
920 host_client = svs.clients + entnum-1;
921 Host_ClientCommands ("%s", string);
929 Returns a chain of entities that have origins within a spherical area
931 findradius (origin, radius)
934 static void VM_SV_findradius (void)
936 prvm_edict_t *ent, *chain;
937 vec_t radius, radius2;
938 vec3_t org, eorg, mins, maxs;
941 static prvm_edict_t *touchedicts[MAX_EDICTS];
944 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
947 chainfield = PRVM_G_INT(OFS_PARM2);
949 chainfield = prog->fieldoffsets.chain;
951 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
953 chain = (prvm_edict_t *)prog->edicts;
955 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
956 radius = PRVM_G_FLOAT(OFS_PARM1);
957 radius2 = radius * radius;
959 mins[0] = org[0] - (radius + 1);
960 mins[1] = org[1] - (radius + 1);
961 mins[2] = org[2] - (radius + 1);
962 maxs[0] = org[0] + (radius + 1);
963 maxs[1] = org[1] + (radius + 1);
964 maxs[2] = org[2] + (radius + 1);
965 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
966 if (numtouchedicts > MAX_EDICTS)
968 // this never happens
969 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
970 numtouchedicts = MAX_EDICTS;
972 for (i = 0;i < numtouchedicts;i++)
974 ent = touchedicts[i];
975 prog->xfunction->builtinsprofile++;
976 // Quake did not return non-solid entities but darkplaces does
977 // (note: this is the reason you can't blow up fallen zombies)
978 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
980 // LordHavoc: compare against bounding box rather than center so it
981 // doesn't miss large objects, and use DotProduct instead of Length
982 // for a major speedup
983 VectorSubtract(org, ent->fields.server->origin, eorg);
984 if (sv_gameplayfix_findradiusdistancetobox.integer)
986 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
987 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
988 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
991 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
992 if (DotProduct(eorg, eorg) < radius2)
994 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
999 VM_RETURN_EDICT(chain);
1002 static void VM_SV_precache_sound (void)
1004 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
1005 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1008 static void VM_SV_precache_model (void)
1010 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1011 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1012 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1019 float(float yaw, float dist[, settrace]) walkmove
1022 static void VM_SV_walkmove (void)
1031 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1033 // assume failure if it returns early
1034 PRVM_G_FLOAT(OFS_RETURN) = 0;
1036 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1037 if (ent == prog->edicts)
1039 VM_Warning("walkmove: can not modify world entity\n");
1042 if (ent->priv.server->free)
1044 VM_Warning("walkmove: can not modify free entity\n");
1047 yaw = PRVM_G_FLOAT(OFS_PARM0);
1048 dist = PRVM_G_FLOAT(OFS_PARM1);
1049 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1051 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1054 yaw = yaw*M_PI*2 / 360;
1056 move[0] = cos(yaw)*dist;
1057 move[1] = sin(yaw)*dist;
1060 // save program state, because SV_movestep may call other progs
1061 oldf = prog->xfunction;
1062 oldself = prog->globals.server->self;
1064 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1067 // restore program state
1068 prog->xfunction = oldf;
1069 prog->globals.server->self = oldself;
1079 static void VM_SV_droptofloor (void)
1085 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1087 // assume failure if it returns early
1088 PRVM_G_FLOAT(OFS_RETURN) = 0;
1090 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1091 if (ent == prog->edicts)
1093 VM_Warning("droptofloor: can not modify world entity\n");
1096 if (ent->priv.server->free)
1098 VM_Warning("droptofloor: can not modify free entity\n");
1102 VectorCopy (ent->fields.server->origin, end);
1105 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1106 SV_UnstickEntity(ent);
1108 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1109 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1112 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]);
1113 VectorAdd(ent->fields.server->origin, offset, org);
1114 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1115 VectorSubtract(trace.endpos, offset, trace.endpos);
1116 if (trace.startsolid)
1118 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]);
1119 SV_UnstickEntity(ent);
1121 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1122 ent->fields.server->groundentity = 0;
1123 PRVM_G_FLOAT(OFS_RETURN) = 1;
1125 else if (trace.fraction < 1)
1127 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]);
1128 VectorCopy (trace.endpos, ent->fields.server->origin);
1129 SV_UnstickEntity(ent);
1131 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1132 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1133 PRVM_G_FLOAT(OFS_RETURN) = 1;
1134 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1135 ent->priv.server->suspendedinairflag = true;
1140 if (trace.fraction != 1)
1142 if (trace.fraction < 1)
1143 VectorCopy (trace.endpos, ent->fields.server->origin);
1145 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1146 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1147 PRVM_G_FLOAT(OFS_RETURN) = 1;
1148 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1149 ent->priv.server->suspendedinairflag = true;
1158 void(float style, string value) lightstyle
1161 static void VM_SV_lightstyle (void)
1168 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1170 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1171 val = PRVM_G_STRING(OFS_PARM1);
1173 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1174 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1177 // change the string in sv
1178 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1180 // send message to all clients on this server
1181 if (sv.state != ss_active)
1184 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1186 if (client->active && client->netconnection)
1188 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1189 MSG_WriteChar (&client->netconnection->message,style);
1190 MSG_WriteString (&client->netconnection->message, val);
1200 static void VM_SV_checkbottom (void)
1202 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1203 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1211 static void VM_SV_pointcontents (void)
1213 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1214 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1221 Pick a vector for the player to shoot along
1222 vector aim(entity, missilespeed)
1225 static void VM_SV_aim (void)
1227 prvm_edict_t *ent, *check, *bestent;
1228 vec3_t start, dir, end, bestdir;
1231 float dist, bestdist;
1234 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1236 // assume failure if it returns early
1237 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1238 // if sv_aim is so high it can't possibly accept anything, skip out early
1239 if (sv_aim.value >= 1)
1242 ent = PRVM_G_EDICT(OFS_PARM0);
1243 if (ent == prog->edicts)
1245 VM_Warning("aim: can not use world entity\n");
1248 if (ent->priv.server->free)
1250 VM_Warning("aim: can not use free entity\n");
1253 //speed = PRVM_G_FLOAT(OFS_PARM1);
1255 VectorCopy (ent->fields.server->origin, start);
1258 // try sending a trace straight
1259 VectorCopy (prog->globals.server->v_forward, dir);
1260 VectorMA (start, 2048, dir, end);
1261 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1262 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1263 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1265 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1270 // try all possible entities
1271 VectorCopy (dir, bestdir);
1272 bestdist = sv_aim.value;
1275 check = PRVM_NEXT_EDICT(prog->edicts);
1276 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1278 prog->xfunction->builtinsprofile++;
1279 if (check->fields.server->takedamage != DAMAGE_AIM)
1283 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1284 continue; // don't aim at teammate
1285 for (j=0 ; j<3 ; j++)
1286 end[j] = check->fields.server->origin[j]
1287 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1288 VectorSubtract (end, start, dir);
1289 VectorNormalize (dir);
1290 dist = DotProduct (dir, prog->globals.server->v_forward);
1291 if (dist < bestdist)
1292 continue; // to far to turn
1293 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1294 if (tr.ent == check)
1295 { // can shoot at this one
1303 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1304 dist = DotProduct (dir, prog->globals.server->v_forward);
1305 VectorScale (prog->globals.server->v_forward, dist, end);
1307 VectorNormalize (end);
1308 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1312 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1317 ===============================================================================
1321 ===============================================================================
1324 #define MSG_BROADCAST 0 // unreliable to all
1325 #define MSG_ONE 1 // reliable to one (msg_entity)
1326 #define MSG_ALL 2 // reliable to all
1327 #define MSG_INIT 3 // write to the init string
1328 #define MSG_ENTITY 5
1330 sizebuf_t *WriteDest (void)
1336 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1340 return &sv.datagram;
1343 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1344 entnum = PRVM_NUM_FOR_EDICT(ent);
1345 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1347 VM_Warning ("WriteDest: tried to write to non-client\n");
1348 return &sv.reliable_datagram;
1351 return &svs.clients[entnum-1].netconnection->message;
1354 VM_Warning ("WriteDest: bad destination\n");
1356 return &sv.reliable_datagram;
1362 return sv.writeentitiestoclient_msg;
1368 static void VM_SV_WriteByte (void)
1370 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1371 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1374 static void VM_SV_WriteChar (void)
1376 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1377 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1380 static void VM_SV_WriteShort (void)
1382 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1383 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1386 static void VM_SV_WriteLong (void)
1388 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1389 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1392 static void VM_SV_WriteAngle (void)
1394 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1395 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1398 static void VM_SV_WriteCoord (void)
1400 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1401 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1404 static void VM_SV_WriteString (void)
1406 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1407 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1410 static void VM_SV_WriteUnterminatedString (void)
1412 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1413 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1417 static void VM_SV_WriteEntity (void)
1419 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1420 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1423 // writes a picture as at most size bytes of data
1425 // IMGNAME \0 SIZE(short) IMGDATA
1426 // if failed to read/compress:
1428 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1429 static void VM_SV_WritePicture (void)
1431 const char *imgname;
1435 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1437 imgname = PRVM_G_STRING(OFS_PARM1);
1438 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1442 MSG_WriteString(WriteDest(), imgname);
1443 if(Image_Compress(imgname, size, &buf, &size))
1446 MSG_WriteShort(WriteDest(), size);
1447 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1452 MSG_WriteShort(WriteDest(), 0);
1456 //////////////////////////////////////////////////////////
1458 static void VM_SV_makestatic (void)
1463 // allow 0 parameters due to an id1 qc bug in which this function is used
1464 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1465 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1467 if (prog->argc >= 1)
1468 ent = PRVM_G_EDICT(OFS_PARM0);
1470 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1471 if (ent == prog->edicts)
1473 VM_Warning("makestatic: can not modify world entity\n");
1476 if (ent->priv.server->free)
1478 VM_Warning("makestatic: can not modify free entity\n");
1483 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1488 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1489 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1490 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1492 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1494 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1495 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1496 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1500 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1501 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1502 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1505 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1506 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1507 for (i=0 ; i<3 ; i++)
1509 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1510 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1513 // throw the entity away now
1517 //=============================================================================
1524 static void VM_SV_setspawnparms (void)
1530 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1532 ent = PRVM_G_EDICT(OFS_PARM0);
1533 i = PRVM_NUM_FOR_EDICT(ent);
1534 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1536 Con_Print("tried to setspawnparms on a non-client\n");
1540 // copy spawn parms out of the client_t
1541 client = svs.clients + i-1;
1542 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1543 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1550 Returns a color vector indicating the lighting at the requested point.
1552 (Internal Operation note: actually measures the light beneath the point, just like
1553 the model lighting on the client)
1558 static void VM_SV_getlight (void)
1560 vec3_t ambientcolor, diffusecolor, diffusenormal;
1562 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1563 p = PRVM_G_VECTOR(OFS_PARM0);
1564 VectorClear(ambientcolor);
1565 VectorClear(diffusecolor);
1566 VectorClear(diffusenormal);
1567 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1568 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1569 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1574 unsigned char type; // 1/2/8 or other value if isn't used
1578 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1579 static int vm_customstats_last;
1581 void VM_CustomStats_Clear (void)
1585 Z_Free(vm_customstats);
1586 vm_customstats = NULL;
1587 vm_customstats_last = -1;
1591 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1599 for(i=0; i<vm_customstats_last+1 ;i++)
1601 if(!vm_customstats[i].type)
1603 switch(vm_customstats[i].type)
1605 //string as 16 bytes
1608 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1609 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1610 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1611 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1612 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1614 //float field sent as-is
1616 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1618 //integer value of float field
1620 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1628 // void(float index, float type, .void field) SV_AddStat = #232;
1629 // Set up an auto-sent player stat.
1630 // Client's get thier own fields sent to them. Index may not be less than 32.
1631 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1632 // 1: string (4 stats carrying a total of 16 charactures)
1633 // 2: float (one stat, float converted to an integer for transportation)
1634 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1635 static void VM_SV_AddStat (void)
1640 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1644 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1647 VM_Warning("PF_SV_AddStat: not enough memory\n");
1651 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1652 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1653 off = PRVM_G_INT (OFS_PARM2);
1658 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1661 if(i >= (MAX_CL_STATS-32))
1663 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1666 if(i > (MAX_CL_STATS-32-4) && type == 1)
1668 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1671 vm_customstats[i].type = type;
1672 vm_customstats[i].fieldoffset = off;
1673 if(vm_customstats_last < i)
1674 vm_customstats_last = i;
1681 copies data from one entity to another
1683 copyentity(src, dst)
1686 static void VM_SV_copyentity (void)
1688 prvm_edict_t *in, *out;
1689 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1690 in = PRVM_G_EDICT(OFS_PARM0);
1691 if (in == prog->edicts)
1693 VM_Warning("copyentity: can not read world entity\n");
1696 if (in->priv.server->free)
1698 VM_Warning("copyentity: can not read free entity\n");
1701 out = PRVM_G_EDICT(OFS_PARM1);
1702 if (out == prog->edicts)
1704 VM_Warning("copyentity: can not modify world entity\n");
1707 if (out->priv.server->free)
1709 VM_Warning("copyentity: can not modify free entity\n");
1712 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1721 sets the color of a client and broadcasts the update to all connected clients
1723 setcolor(clientent, value)
1726 static void VM_SV_setcolor (void)
1732 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1733 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1734 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1736 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1738 Con_Print("tried to setcolor a non-client\n");
1742 client = svs.clients + entnum-1;
1745 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1747 client->edict->fields.server->team = (i & 15) + 1;
1750 if (client->old_colors != client->colors)
1752 client->old_colors = client->colors;
1753 // send notification to all clients
1754 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1755 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1756 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1764 effect(origin, modelname, startframe, framecount, framerate)
1767 static void VM_SV_effect (void)
1771 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1772 s = PRVM_G_STRING(OFS_PARM1);
1775 VM_Warning("effect: no model specified\n");
1779 i = SV_ModelIndex(s, 1);
1782 VM_Warning("effect: model not precached\n");
1786 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1788 VM_Warning("effect: framecount < 1\n");
1792 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1794 VM_Warning("effect: framerate < 1\n");
1798 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));
1801 static void VM_SV_te_blood (void)
1803 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1804 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1806 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1807 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1813 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1814 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1815 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1817 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1818 SV_FlushBroadcastMessages();
1821 static void VM_SV_te_bloodshower (void)
1823 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1824 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1826 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1827 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1839 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1840 SV_FlushBroadcastMessages();
1843 static void VM_SV_te_explosionrgb (void)
1845 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1846 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1847 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1849 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1850 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1851 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1853 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1854 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1855 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1856 SV_FlushBroadcastMessages();
1859 static void VM_SV_te_particlecube (void)
1861 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1862 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1864 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1865 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1879 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1881 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1882 // gravity true/false
1883 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1885 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1886 SV_FlushBroadcastMessages();
1889 static void VM_SV_te_particlerain (void)
1891 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1892 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1894 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1895 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1909 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1911 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1912 SV_FlushBroadcastMessages();
1915 static void VM_SV_te_particlesnow (void)
1917 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1918 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1920 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1921 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1929 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1935 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1937 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1938 SV_FlushBroadcastMessages();
1941 static void VM_SV_te_spark (void)
1943 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1944 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1946 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1947 MSG_WriteByte(&sv.datagram, TE_SPARK);
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);
1953 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1954 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1955 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1957 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1958 SV_FlushBroadcastMessages();
1961 static void VM_SV_te_gunshotquad (void)
1963 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1964 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1965 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1970 SV_FlushBroadcastMessages();
1973 static void VM_SV_te_spikequad (void)
1975 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1976 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1977 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1982 SV_FlushBroadcastMessages();
1985 static void VM_SV_te_superspikequad (void)
1987 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1988 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1989 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1994 SV_FlushBroadcastMessages();
1997 static void VM_SV_te_explosionquad (void)
1999 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
2000 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2001 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2006 SV_FlushBroadcastMessages();
2009 static void VM_SV_te_smallflash (void)
2011 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2012 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2013 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2018 SV_FlushBroadcastMessages();
2021 static void VM_SV_te_customflash (void)
2023 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2024 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2026 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2027 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2029 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2033 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2035 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2037 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2038 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2039 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2040 SV_FlushBroadcastMessages();
2043 static void VM_SV_te_gunshot (void)
2045 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2046 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2047 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2049 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2050 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2051 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2052 SV_FlushBroadcastMessages();
2055 static void VM_SV_te_spike (void)
2057 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2058 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2059 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2061 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2063 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2064 SV_FlushBroadcastMessages();
2067 static void VM_SV_te_superspike (void)
2069 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2070 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2071 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2073 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2074 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2075 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2076 SV_FlushBroadcastMessages();
2079 static void VM_SV_te_explosion (void)
2081 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2082 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2083 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2085 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2086 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2087 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2088 SV_FlushBroadcastMessages();
2091 static void VM_SV_te_tarexplosion (void)
2093 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2094 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2095 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2100 SV_FlushBroadcastMessages();
2103 static void VM_SV_te_wizspike (void)
2105 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2106 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2107 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2109 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2110 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2111 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2112 SV_FlushBroadcastMessages();
2115 static void VM_SV_te_knightspike (void)
2117 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2118 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2119 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2121 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2122 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2123 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2124 SV_FlushBroadcastMessages();
2127 static void VM_SV_te_lavasplash (void)
2129 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2130 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2131 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2133 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2134 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2135 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2136 SV_FlushBroadcastMessages();
2139 static void VM_SV_te_teleport (void)
2141 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2142 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2143 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2145 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2146 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2147 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2148 SV_FlushBroadcastMessages();
2151 static void VM_SV_te_explosion2 (void)
2153 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2154 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2155 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2157 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2158 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2159 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2161 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2162 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2163 SV_FlushBroadcastMessages();
2166 static void VM_SV_te_lightning1 (void)
2168 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2169 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2170 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2172 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2174 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2175 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2176 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2178 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2179 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2180 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2181 SV_FlushBroadcastMessages();
2184 static void VM_SV_te_lightning2 (void)
2186 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2187 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2188 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2190 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2192 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2193 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2194 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2196 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2197 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2198 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2199 SV_FlushBroadcastMessages();
2202 static void VM_SV_te_lightning3 (void)
2204 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2205 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2206 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2208 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2210 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2211 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2212 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2214 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2215 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2216 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2217 SV_FlushBroadcastMessages();
2220 static void VM_SV_te_beam (void)
2222 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2223 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2224 MSG_WriteByte(&sv.datagram, TE_BEAM);
2226 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2228 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2229 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2230 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2232 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2233 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2234 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2235 SV_FlushBroadcastMessages();
2238 static void VM_SV_te_plasmaburn (void)
2240 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2241 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2242 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2243 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2244 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2245 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2246 SV_FlushBroadcastMessages();
2249 static void VM_SV_te_flamejet (void)
2251 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2252 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2253 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2255 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2256 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2257 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2259 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2260 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2261 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2263 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2264 SV_FlushBroadcastMessages();
2267 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2268 //this function originally written by KrimZon, made shorter by LordHavoc
2269 static void VM_SV_clientcommand (void)
2271 client_t *temp_client;
2273 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2275 //find client for this entity
2276 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2277 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2279 Con_Print("PF_clientcommand: entity is not a client\n");
2283 temp_client = host_client;
2284 host_client = svs.clients + i;
2285 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2286 host_client = temp_client;
2289 //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)
2290 static void VM_SV_setattachment (void)
2292 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2293 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2294 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2297 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2299 if (e == prog->edicts)
2301 VM_Warning("setattachment: can not modify world entity\n");
2304 if (e->priv.server->free)
2306 VM_Warning("setattachment: can not modify free entity\n");
2310 if (tagentity == NULL)
2311 tagentity = prog->edicts;
2313 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2315 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2317 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2320 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2322 model = SV_GetModelFromEdict(tagentity);
2325 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2327 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);
2330 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));
2334 /////////////////////////////////////////
2335 // DP_MD3_TAGINFO extension coded by VorteX
2337 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2341 i = (int)e->fields.server->modelindex;
2342 if (i < 1 || i >= MAX_MODELS)
2345 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2348 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2355 Matrix4x4_CreateIdentity(tag_localmatrix);
2357 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2359 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2370 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2374 float pitchsign = 1;
2377 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2378 if (val && val->_float != 0)
2379 scale = val->_float;
2382 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 * cl_viewmodel_scale.value);
2385 pitchsign = SV_GetPitchSign(ent);
2386 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], pitchsign * ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale);
2390 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2393 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2395 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2396 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2397 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2398 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2400 *out = identitymatrix;
2404 // Warnings/errors code:
2405 // 0 - normal (everything all-right)
2408 // 3 - null or non-precached model
2409 // 4 - no tags with requested index
2410 // 5 - runaway loop at attachment chain
2411 extern cvar_t cl_bob;
2412 extern cvar_t cl_bobcycle;
2413 extern cvar_t cl_bobup;
2414 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2418 int modelindex, attachloop;
2419 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2422 *out = identitymatrix; // warnings and errors return identical matrix
2424 if (ent == prog->edicts)
2426 if (ent->priv.server->free)
2429 modelindex = (int)ent->fields.server->modelindex;
2430 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2433 model = SV_GetModelByIndex(modelindex);
2435 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2436 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2437 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2439 tagmatrix = identitymatrix;
2440 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2444 if (attachloop >= 256) // prevent runaway looping
2446 // apply transformation by child's tagindex on parent entity and then
2447 // by parent entity itself
2448 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2449 if (ret && attachloop == 0)
2451 SV_GetEntityMatrix(ent, &entitymatrix, false);
2452 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2453 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2454 // next iteration we process the parent entity
2455 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2457 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2458 ent = PRVM_EDICT_NUM(val->edict);
2465 // RENDER_VIEWMODEL magic
2466 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2468 Matrix4x4_Copy(&tagmatrix, out);
2469 ent = PRVM_EDICT_NUM(val->edict);
2471 SV_GetEntityMatrix(ent, &entitymatrix, true);
2472 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2475 // Cl_bob, ported from rendering code
2476 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2479 // LordHavoc: this code is *weird*, but not replacable (I think it
2480 // should be done in QC on the server, but oh well, quake is quake)
2481 // LordHavoc: figured out bobup: the time at which the sin is at 180
2482 // degrees (which allows lengthening or squishing the peak or valley)
2483 cycle = sv.time/cl_bobcycle.value;
2484 cycle -= (int)cycle;
2485 if (cycle < cl_bobup.value)
2486 cycle = sin(M_PI * cycle / cl_bobup.value);
2488 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2489 // bob is proportional to velocity in the xy plane
2490 // (don't count Z, or jumping messes it up)
2491 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;
2492 bob = bob*0.3 + bob*0.7*cycle;
2493 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2500 //float(entity ent, string tagname) gettagindex;
2502 static void VM_SV_gettagindex (void)
2505 const char *tag_name;
2508 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2510 ent = PRVM_G_EDICT(OFS_PARM0);
2511 tag_name = PRVM_G_STRING(OFS_PARM1);
2513 if (ent == prog->edicts)
2515 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2518 if (ent->priv.server->free)
2520 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2525 if (!SV_GetModelFromEdict(ent))
2526 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2529 tag_index = SV_GetTagIndex(ent, tag_name);
2531 if(developer_extra.integer)
2532 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2534 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2537 //vector(entity ent, float tagindex) gettaginfo;
2538 static void VM_SV_gettaginfo (void)
2542 matrix4x4_t tag_matrix;
2543 matrix4x4_t tag_localmatrix;
2545 const char *tagname;
2548 vec3_t fo, le, up, trans;
2549 const dp_model_t *model;
2551 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2553 e = PRVM_G_EDICT(OFS_PARM0);
2554 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2556 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2557 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2558 VectorScale(le, -1, prog->globals.server->v_right);
2559 model = SV_GetModelFromEdict(e);
2560 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2561 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2562 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2563 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2564 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2566 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2567 val->_float = parentindex;
2568 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2569 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2570 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2571 VectorCopy(trans, val->vector);
2572 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2573 VectorCopy(fo, val->vector);
2574 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2575 VectorScale(le, -1, val->vector);
2576 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2577 VectorCopy(up, val->vector);
2582 VM_Warning("gettagindex: can't affect world entity\n");
2585 VM_Warning("gettagindex: can't affect free entity\n");
2588 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2591 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2594 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2599 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2600 static void VM_SV_dropclient (void)
2603 client_t *oldhostclient;
2604 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2605 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2606 if (clientnum < 0 || clientnum >= svs.maxclients)
2608 VM_Warning("dropclient: not a client\n");
2611 if (!svs.clients[clientnum].active)
2613 VM_Warning("dropclient: that client slot is not connected\n");
2616 oldhostclient = host_client;
2617 host_client = svs.clients + clientnum;
2618 SV_DropClient(false);
2619 host_client = oldhostclient;
2622 //entity() spawnclient (DP_SV_BOTCLIENT)
2623 static void VM_SV_spawnclient (void)
2627 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2628 prog->xfunction->builtinsprofile += 2;
2630 for (i = 0;i < svs.maxclients;i++)
2632 if (!svs.clients[i].active)
2634 prog->xfunction->builtinsprofile += 100;
2635 SV_ConnectClient (i, NULL);
2636 // this has to be set or else ClientDisconnect won't be called
2637 // we assume the qc will call ClientConnect...
2638 svs.clients[i].clientconnectcalled = true;
2639 ed = PRVM_EDICT_NUM(i + 1);
2643 VM_RETURN_EDICT(ed);
2646 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2647 static void VM_SV_clienttype (void)
2650 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2651 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2652 if (clientnum < 0 || clientnum >= svs.maxclients)
2653 PRVM_G_FLOAT(OFS_RETURN) = 3;
2654 else if (!svs.clients[clientnum].active)
2655 PRVM_G_FLOAT(OFS_RETURN) = 0;
2656 else if (svs.clients[clientnum].netconnection)
2657 PRVM_G_FLOAT(OFS_RETURN) = 1;
2659 PRVM_G_FLOAT(OFS_RETURN) = 2;
2666 string(string key) serverkey
2669 void VM_SV_serverkey(void)
2671 char string[VM_STRINGTEMP_LENGTH];
2672 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2673 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2674 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2677 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2678 static void VM_SV_setmodelindex (void)
2683 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2685 e = PRVM_G_EDICT(OFS_PARM0);
2686 if (e == prog->edicts)
2688 VM_Warning("setmodelindex: can not modify world entity\n");
2691 if (e->priv.server->free)
2693 VM_Warning("setmodelindex: can not modify free entity\n");
2696 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2697 if (i <= 0 || i >= MAX_MODELS)
2699 VM_Warning("setmodelindex: invalid modelindex\n");
2702 if (!sv.model_precache[i][0])
2704 VM_Warning("setmodelindex: model not precached\n");
2708 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2709 e->fields.server->modelindex = i;
2711 mod = SV_GetModelByIndex(i);
2715 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2716 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2718 SetMinMaxSize (e, quakemins, quakemaxs, true);
2721 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2724 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2725 static void VM_SV_modelnameforindex (void)
2728 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2730 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2732 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2733 if (i <= 0 || i >= MAX_MODELS)
2735 VM_Warning("modelnameforindex: invalid modelindex\n");
2738 if (!sv.model_precache[i][0])
2740 VM_Warning("modelnameforindex: model not precached\n");
2744 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2747 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2748 static void VM_SV_particleeffectnum (void)
2751 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2752 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2755 PRVM_G_FLOAT(OFS_RETURN) = i;
2758 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2759 static void VM_SV_trailparticles (void)
2761 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2763 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2766 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2767 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2768 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2769 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2770 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2771 SV_FlushBroadcastMessages();
2774 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2775 static void VM_SV_pointparticles (void)
2777 int effectnum, count;
2779 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2781 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2784 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2785 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2786 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2787 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2788 if (count == 1 && !VectorLength2(vel))
2791 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2792 MSG_WriteShort(&sv.datagram, effectnum);
2793 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2797 // 1+2+12+12+2=29 bytes
2798 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2799 MSG_WriteShort(&sv.datagram, effectnum);
2800 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2801 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2802 MSG_WriteShort(&sv.datagram, count);
2805 SV_FlushBroadcastMessages();
2808 //PF_setpause, // void(float pause) setpause = #531;
2809 static void VM_SV_setpause(void) {
2811 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2812 if (pauseValue != 0) { //pause the game
2814 sv.pausedstart = Sys_DoubleTime();
2815 } else { //disable pause, in case it was enabled
2816 if (sv.paused != 0) {
2821 // send notification to all clients
2822 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2823 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2826 // #263 float(float modlindex) skel_create = #263; // (FTE_CSQC_SKELETONOBJECTS) create a skeleton (be sure to assign this value into .skeletonindex for use), returns skeleton index (1 or higher) on success, returns 0 on failure (for example if the modelindex is not skeletal), it is recommended that you create a new skeleton if you change modelindex.
2827 static void VM_SV_skel_create(void)
2829 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2830 dp_model_t *model = SV_GetModelByIndex(modelindex);
2831 skeleton_t *skeleton;
2833 PRVM_G_FLOAT(OFS_RETURN) = 0;
2834 if (!model || !model->num_bones)
2836 for (i = 0;i < MAX_EDICTS;i++)
2837 if (!prog->skeletons[i])
2839 if (i == MAX_EDICTS)
2841 prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2842 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2843 skeleton->model = model;
2844 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2845 // initialize to identity matrices
2846 for (i = 0;i < skeleton->model->num_bones;i++)
2847 skeleton->relativetransforms[i] = identitymatrix;
2850 // #264 float(float skel, entity ent, float modlindex, float retainfrac, float firstbone, float lastbone) skel_build = #264; // (FTE_CSQC_SKELETONOBJECTS) blend in a percentage of standard animation, 0 replaces entirely, 1 does nothing, 0.5 blends half, etc, and this only alters the bones in the specified range for which out of bounds values like 0,100000 are safe (uses .frame, .frame2, .frame3, .frame4, .lerpfrac, .lerpfrac3, .lerpfrac4, .frame1time, .frame2time, .frame3time, .frame4time), returns skel on success, 0 on failure
2851 static void VM_SV_skel_build(void)
2853 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2854 skeleton_t *skeleton;
2855 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2856 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2857 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2858 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2859 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2860 dp_model_t *model = SV_GetModelByIndex(modelindex);
2865 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2866 frameblend_t frameblend[MAX_FRAMEBLENDS];
2867 matrix4x4_t blendedmatrix;
2869 PRVM_G_FLOAT(OFS_RETURN) = 0;
2870 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2872 firstbone = max(0, firstbone);
2873 lastbone = min(lastbone, model->num_bones - 1);
2874 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2875 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2876 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2877 blendfrac = 1.0f - retainfrac;
2878 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2879 frameblend[numblends].lerp *= blendfrac;
2880 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2882 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2883 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2884 for (blendindex = 0;blendindex < numblends;blendindex++)
2886 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2887 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2889 skeleton->relativetransforms[bonenum] = blendedmatrix;
2891 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2894 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2895 static void VM_SV_skel_get_numbones(void)
2897 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2898 skeleton_t *skeleton;
2899 PRVM_G_FLOAT(OFS_RETURN) = 0;
2900 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2902 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2905 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2906 static void VM_SV_skel_get_bonename(void)
2908 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2909 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2910 skeleton_t *skeleton;
2911 PRVM_G_INT(OFS_RETURN) = 0;
2912 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2914 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2916 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2919 // #267 float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS) returns parent num for supplied bonenum, 0 if bonenum has no parent or bone does not exist (returned value is always less than bonenum, you can loop on this)
2920 static void VM_SV_skel_get_boneparent(void)
2922 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2923 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2924 skeleton_t *skeleton;
2925 PRVM_G_FLOAT(OFS_RETURN) = 0;
2926 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2928 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2930 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2933 // #268 float(float skel, string tagname) skel_find_bone = #268; // (FTE_CSQC_SKELETONOBJECTS) get number of bone with specified name, 0 on failure, tagindex (bonenum+1) on success, same as using gettagindex on the modelindex
2934 static void VM_SV_skel_find_bone(void)
2936 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2937 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2938 skeleton_t *skeleton;
2939 PRVM_G_FLOAT(OFS_RETURN) = 0;
2940 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2942 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2945 // #269 vector(float skel, float bonenum) skel_get_bonerel = #269; // (FTE_CSQC_SKELETONOBJECTS) get matrix of bone in skeleton relative to its parent - sets v_forward, v_right, v_up, returns origin (relative to parent bone)
2946 static void VM_SV_skel_get_bonerel(void)
2948 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2949 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2950 skeleton_t *skeleton;
2952 vec3_t forward, left, up, origin;
2953 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2954 VectorClear(prog->globals.client->v_forward);
2955 VectorClear(prog->globals.client->v_right);
2956 VectorClear(prog->globals.client->v_up);
2957 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2959 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2961 matrix = skeleton->relativetransforms[bonenum];
2962 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2963 VectorCopy(forward, prog->globals.client->v_forward);
2964 VectorNegate(left, prog->globals.client->v_right);
2965 VectorCopy(up, prog->globals.client->v_up);
2966 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2969 // #270 vector(float skel, float bonenum) skel_get_boneabs = #270; // (FTE_CSQC_SKELETONOBJECTS) get matrix of bone in skeleton in model space - sets v_forward, v_right, v_up, returns origin (relative to entity)
2970 static void VM_SV_skel_get_boneabs(void)
2972 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2973 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2974 skeleton_t *skeleton;
2977 vec3_t forward, left, up, origin;
2978 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2979 VectorClear(prog->globals.client->v_forward);
2980 VectorClear(prog->globals.client->v_right);
2981 VectorClear(prog->globals.client->v_up);
2982 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2984 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2986 matrix = skeleton->relativetransforms[bonenum];
2987 // convert to absolute
2988 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2991 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2993 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2994 VectorCopy(forward, prog->globals.client->v_forward);
2995 VectorNegate(left, prog->globals.client->v_right);
2996 VectorCopy(up, prog->globals.client->v_up);
2997 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
3000 // #271 void(float skel, float bonenum, vector org) skel_set_bone = #271; // (FTE_CSQC_SKELETONOBJECTS) set matrix of bone relative to its parent, reads v_forward, v_right, v_up, takes origin as parameter (relative to parent bone)
3001 static void VM_SV_skel_set_bone(void)
3003 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3004 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3005 vec3_t forward, left, up, origin;
3006 skeleton_t *skeleton;
3008 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3010 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3012 VectorCopy(prog->globals.client->v_forward, forward);
3013 VectorNegate(prog->globals.client->v_right, left);
3014 VectorCopy(prog->globals.client->v_up, up);
3015 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3016 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3017 skeleton->relativetransforms[bonenum] = matrix;
3020 // #272 void(float skel, float bonenum, vector org) skel_mul_bone = #272; // (FTE_CSQC_SKELETONOBJECTS) transform bone matrix (relative to its parent) by the supplied matrix in v_forward, v_right, v_up, takes origin as parameter (relative to parent bone)
3021 static void VM_SV_skel_mul_bone(void)
3023 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3024 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3025 vec3_t forward, left, up, origin;
3026 skeleton_t *skeleton;
3029 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3031 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3033 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3034 VectorCopy(prog->globals.client->v_forward, forward);
3035 VectorNegate(prog->globals.client->v_right, left);
3036 VectorCopy(prog->globals.client->v_up, up);
3037 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3038 temp = skeleton->relativetransforms[bonenum];
3039 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3042 // #273 void(float skel, float startbone, float endbone, vector org) skel_mul_bones = #273; // (FTE_CSQC_SKELETONOBJECTS) transform bone matrices (relative to their parents) by the supplied matrix in v_forward, v_right, v_up, takes origin as parameter (relative to parent bones)
3043 static void VM_SV_skel_mul_bones(void)
3045 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3046 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3047 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3049 vec3_t forward, left, up, origin;
3050 skeleton_t *skeleton;
3053 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3055 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3056 VectorCopy(prog->globals.client->v_forward, forward);
3057 VectorNegate(prog->globals.client->v_right, left);
3058 VectorCopy(prog->globals.client->v_up, up);
3059 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3060 firstbone = max(0, firstbone);
3061 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3062 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3064 temp = skeleton->relativetransforms[bonenum];
3065 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3069 // #274 void(float skeldst, float skelsrc, float startbone, float endbone) skel_copybones = #274; // (FTE_CSQC_SKELETONOBJECTS) copy bone matrices (relative to their parents) from one skeleton to another, useful for copying a skeleton to a corpse
3070 static void VM_SV_skel_copybones(void)
3072 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3073 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3074 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3075 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3077 skeleton_t *skeletondst;
3078 skeleton_t *skeletonsrc;
3079 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3081 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3083 firstbone = max(0, firstbone);
3084 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3085 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3086 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3087 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3090 // #275 void(float skel) skel_delete = #275; // (FTE_CSQC_SKELETONOBJECTS) deletes skeleton at the beginning of the next frame (you can add the entity, delete the skeleton, renderscene, and it will still work)
3091 static void VM_SV_skel_delete(void)
3093 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3094 skeleton_t *skeleton;
3095 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3098 prog->skeletons[skeletonindex] = NULL;
3101 // #276 float(float modlindex, string framename) frameforname = #276; // (FTE_CSQC_SKELETONOBJECTS) finds number of a specified frame in the animation, returns -1 if no match found
3102 static void VM_SV_frameforname(void)
3104 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3105 dp_model_t *model = SV_GetModelByIndex(modelindex);
3106 const char *name = PRVM_G_STRING(OFS_PARM1);
3108 PRVM_G_FLOAT(OFS_RETURN) = -1;
3109 if (!model || !model->animscenes)
3111 for (i = 0;i < model->numframes;i++)
3113 if (!strcasecmp(model->animscenes[i].name, name))
3115 PRVM_G_FLOAT(OFS_RETURN) = i;
3121 // #277 float(float modlindex, float framenum) frameduration = #277; // (FTE_CSQC_SKELETONOBJECTS) returns the intended play time (in seconds) of the specified framegroup, if it does not exist the result is 0, if it is a single frame it may be a small value around 0.1 or 0.
3122 static void VM_SV_frameduration(void)
3124 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3125 dp_model_t *model = SV_GetModelByIndex(modelindex);
3126 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3127 PRVM_G_FLOAT(OFS_RETURN) = 0;
3128 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3130 if (model->animscenes[framenum].framerate)
3131 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3135 prvm_builtin_t vm_sv_builtins[] = {
3136 NULL, // #0 NULL function (not callable) (QUAKE)
3137 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3138 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3139 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3140 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3141 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3142 VM_break, // #6 void() break (QUAKE)
3143 VM_random, // #7 float() random (QUAKE)
3144 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3145 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3146 VM_error, // #10 void(string e) error (QUAKE)
3147 VM_objerror, // #11 void(string e) objerror (QUAKE)
3148 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3149 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3150 VM_spawn, // #14 entity() spawn (QUAKE)
3151 VM_remove, // #15 void(entity e) remove (QUAKE)
3152 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3153 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3154 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3155 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3156 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3157 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3158 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3159 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3160 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3161 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3162 VM_ftos, // #26 string(float f) ftos (QUAKE)
3163 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3164 VM_coredump, // #28 void() coredump (QUAKE)
3165 VM_traceon, // #29 void() traceon (QUAKE)
3166 VM_traceoff, // #30 void() traceoff (QUAKE)
3167 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3168 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3169 NULL, // #33 (QUAKE)
3170 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3171 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3172 VM_rint, // #36 float(float v) rint (QUAKE)
3173 VM_floor, // #37 float(float v) floor (QUAKE)
3174 VM_ceil, // #38 float(float v) ceil (QUAKE)
3175 NULL, // #39 (QUAKE)
3176 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3177 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3178 NULL, // #42 (QUAKE)
3179 VM_fabs, // #43 float(float f) fabs (QUAKE)
3180 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3181 VM_cvar, // #45 float(string s) cvar (QUAKE)
3182 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3183 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3184 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3185 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3186 NULL, // #50 (QUAKE)
3187 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3188 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3189 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3190 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3191 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3192 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3193 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3194 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3195 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3196 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3197 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3198 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3199 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3200 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3201 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3202 NULL, // #66 (QUAKE)
3203 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3204 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3205 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3206 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3207 NULL, // #71 (QUAKE)
3208 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3209 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3210 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3211 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3212 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3213 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3214 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3215 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3216 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3217 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3218 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3219 NULL, // #83 (QUAKE)
3220 NULL, // #84 (QUAKE)
3221 NULL, // #85 (QUAKE)
3222 NULL, // #86 (QUAKE)
3223 NULL, // #87 (QUAKE)
3224 NULL, // #88 (QUAKE)
3225 NULL, // #89 (QUAKE)
3226 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3227 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3228 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3229 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3230 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3231 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3232 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3233 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3234 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3235 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3236 // FrikaC and Telejano range #100-#199
3247 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3248 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3249 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3250 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3251 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3252 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3253 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3254 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3255 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3256 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3337 // FTEQW range #200-#299
3356 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3359 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3360 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3361 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3362 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3363 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3364 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3365 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3366 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3367 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3368 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3370 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3378 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3401 VM_SV_skel_create, // #263 float(float modlindex) skel_create = #263; // (DP_SKELETONOBJECTS) create a skeleton (be sure to assign this value into .skeletonindex for use), returns skeleton index (1 or higher) on success, returns 0 on failure (for example if the modelindex is not skeletal), it is recommended that you create a new skeleton if you change modelindex.
3402 VM_SV_skel_build, // #264 float(float skel, entity ent, float modlindex, float retainfrac, float firstbone, float lastbone) skel_build = #264; // (DP_SKELETONOBJECTS) blend in a percentage of standard animation, 0 replaces entirely, 1 does nothing, 0.5 blends half, etc, and this only alters the bones in the specified range for which out of bounds values like 0,100000 are safe (uses .frame, .frame2, .frame3, .frame4, .lerpfrac, .lerpfrac3, .lerpfrac4, .frame1time, .frame2time, .frame3time, .frame4time), returns skel on success, 0 on failure
3403 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3404 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3405 VM_SV_skel_get_boneparent, // #267 float(float skel, float bonenum) skel_get_boneparent = #267; // (DP_SKELETONOBJECTS) returns parent num for supplied bonenum, -1 if bonenum has no parent or bone does not exist (returned value is always less than bonenum, you can loop on this)
3406 VM_SV_skel_find_bone, // #268 float(float skel, string tagname) skel_find_bone = #268; // (DP_SKELETONOBJECTS) get number of bone with specified name, 0 on failure, tagindex (bonenum+1) on success, same as using gettagindex on the modelindex
3407 VM_SV_skel_get_bonerel, // #269 vector(float skel, float bonenum) skel_get_bonerel = #269; // (DP_SKELETONOBJECTS) get matrix of bone in skeleton relative to its parent - sets v_forward, v_right, v_up, returns origin (relative to parent bone)
3408 VM_SV_skel_get_boneabs, // #270 vector(float skel, float bonenum) skel_get_boneabs = #270; // (DP_SKELETONOBJECTS) get matrix of bone in skeleton in model space - sets v_forward, v_right, v_up, returns origin (relative to entity)
3409 VM_SV_skel_set_bone, // #271 void(float skel, float bonenum, vector org) skel_set_bone = #271; // (DP_SKELETONOBJECTS) set matrix of bone relative to its parent, reads v_forward, v_right, v_up, takes origin as parameter (relative to parent bone)
3410 VM_SV_skel_mul_bone, // #272 void(float skel, float bonenum, vector org) skel_mul_bone = #272; // (DP_SKELETONOBJECTS) transform bone matrix (relative to its parent) by the supplied matrix in v_forward, v_right, v_up, takes origin as parameter (relative to parent bone)
3411 VM_SV_skel_mul_bones, // #273 void(float skel, float startbone, float endbone, vector org) skel_mul_bones = #273; // (DP_SKELETONOBJECTS) transform bone matrices (relative to their parents) by the supplied matrix in v_forward, v_right, v_up, takes origin as parameter (relative to parent bones)
3412 VM_SV_skel_copybones, // #274 void(float skeldst, float skelsrc, float startbone, float endbone) skel_copybones = #274; // (DP_SKELETONOBJECTS) copy bone matrices (relative to their parents) from one skeleton to another, useful for copying a skeleton to a corpse
3413 VM_SV_skel_delete, // #275 void(float skel) skel_delete = #275; // (DP_SKELETONOBJECTS) deletes skeleton at the beginning of the next frame (you can add the entity, delete the skeleton, renderscene, and it will still work)
3414 VM_SV_frameforname, // #276 float(float modlindex, string framename) frameforname = #276; // (DP_SKELETONOBJECTS) finds number of a specified frame in the animation, returns -1 if no match found
3415 VM_SV_frameduration, // #277 float(float modlindex, float framenum) frameduration = #277; // (DP_SKELETONOBJECTS) returns the intended play time (in seconds) of the specified framegroup, if it does not exist the result is 0, if it is a single frame it may be a small value around 0.1 or 0.
3438 // CSQC range #300-#399
3439 NULL, // #300 void() clearscene (EXT_CSQC)
3440 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3441 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3442 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3443 NULL, // #304 void() renderscene (EXT_CSQC)
3444 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3445 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3446 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3447 NULL, // #308 void() R_EndPolygon
3449 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3450 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3454 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3455 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3456 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3457 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3458 NULL, // #319 void(string name) freepic (EXT_CSQC)
3459 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3460 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3461 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3462 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3463 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3464 NULL, // #325 void(void) drawresetcliparea
3469 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3470 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3471 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3472 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3473 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3474 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3475 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3476 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3477 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3478 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3479 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3480 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3481 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3482 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3483 NULL, // #344 vector() getmousepos (EXT_CSQC)
3484 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3485 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3486 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3487 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3488 NULL, // #349 float() isdemo (EXT_CSQC)
3489 VM_isserver, // #350 float() isserver (EXT_CSQC)
3490 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3491 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3492 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3493 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3499 NULL, // #360 float() readbyte (EXT_CSQC)
3500 NULL, // #361 float() readchar (EXT_CSQC)
3501 NULL, // #362 float() readshort (EXT_CSQC)
3502 NULL, // #363 float() readlong (EXT_CSQC)
3503 NULL, // #364 float() readcoord (EXT_CSQC)
3504 NULL, // #365 float() readangle (EXT_CSQC)
3505 NULL, // #366 string() readstring (EXT_CSQC)
3506 NULL, // #367 float() readfloat (EXT_CSQC)
3539 // LordHavoc's range #400-#499
3540 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3541 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3542 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3543 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3544 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3545 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3546 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3547 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3548 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)
3549 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3550 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3551 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3552 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3553 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3554 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3555 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3556 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3557 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3558 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3559 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3560 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3561 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3566 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3567 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3568 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3569 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3570 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3571 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3572 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3573 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3574 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3575 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3576 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3577 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3578 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3579 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3580 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3581 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3582 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3583 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3584 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3585 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3586 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3587 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3588 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3589 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3590 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3591 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3592 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3593 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3594 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3595 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3596 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3597 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3599 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3600 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3601 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3602 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3603 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3604 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3605 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3606 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3607 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3608 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3609 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3611 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3612 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3613 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3614 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3615 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3616 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3617 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3618 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3619 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3620 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3621 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3622 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3623 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3624 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3625 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3626 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3634 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3635 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3636 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3637 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3638 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3639 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3640 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3641 VM_SV_WritePicture, // #501
3643 VM_whichpack, // #503 string(string) whichpack = #503;
3650 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3651 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3652 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3653 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3654 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3655 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3656 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3657 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3658 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3659 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3669 VM_loadfromdata, // #529
3670 VM_loadfromfile, // #530
3671 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3673 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3674 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3745 VM_callfunction, // #605
3746 VM_writetofile, // #606
3747 VM_isfunction, // #607
3753 VM_parseentitydata, // #613
3764 VM_SV_getextresponse, // #624 string getextresponse(void)
3767 VM_sprintf, // #627 string sprintf(string format, ...)
3768 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3769 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3773 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3775 void VM_SV_Cmd_Init(void)
3780 void VM_SV_Cmd_Reset(void)
3782 World_End(&sv.world);
3783 if(prog->funcoffsets.SV_Shutdown)
3785 func_t s = prog->funcoffsets.SV_Shutdown;
3786 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3787 PRVM_ExecuteProgram(s,"SV_Shutdown() required");