6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
36 "DP_ENT_CUSTOMCOLORMAP "
37 "DP_ENT_EXTERIORMODELTOCLIENT "
39 "DP_ENT_LOWPRECISION "
43 "DP_GFX_EXTERNALTEXTURES "
44 "DP_GFX_EXTERNALTEXTURES_PERMAP "
46 "DP_GFX_QUAKE3MODELTAGS "
50 "DP_HALFLIFE_MAP_CVAR "
56 "DP_MOVETYPEBOUNCEMISSILE "
59 "DP_QC_ASINACOSATANATAN2TAN "
64 "DP_QC_CVAR_DEFSTRING "
71 "DP_QC_FINDCHAINFLAGS "
72 "DP_QC_FINDCHAINFLOAT "
78 "DP_QC_GETSURFACEPOINTATTRIBUTE "
81 "DP_QC_MULTIPLETEMPSTRINGS "
82 "DP_QC_NUM_FOR_EDICT "
84 "DP_QC_SINCOSSQRTPOW "
86 "DP_QC_STRINGBUFFERS "
87 "DP_QC_STRINGCOLORFUNCTIONS "
88 "DP_QC_STRING_CASE_FUNCTIONS "
90 "DP_QC_TOKENIZEBYSEPARATOR "
91 "DP_QC_TOKENIZE_CONSOLE "
94 "DP_QC_TRACE_MOVETYPE_HITMODEL "
95 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
96 "DP_QC_UNLIMITEDTEMPSTRINGS "
99 "DP_QC_VECTOANGLES_WITH_ROLL "
100 "DP_QC_VECTORVECTORS "
107 "DP_SND_DIRECTIONLESSATTNNONE "
114 "DP_SV_CLIENTCOLORS "
117 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
118 "DP_SV_DRAWONLYTOCLIENT "
121 "DP_SV_ENTITYCONTENTSTRANSITION "
122 "DP_SV_MODELFLAGS_AS_EFFECTS "
123 "DP_SV_MOVETYPESTEP_LANDEVENT "
125 "DP_SV_NODRAWTOCLIENT "
126 "DP_SV_ONENTITYNOSPAWNFUNCTION "
128 "DP_SV_PLAYERPHYSICS "
129 "DP_SV_POINTPARTICLES "
131 "DP_SV_PRECACHEANYTIME "
135 "DP_SV_ROTATINGBMODEL "
139 "DP_SV_SPAWNFUNC_PREFIX "
140 "DP_SV_WRITEPICTURE "
141 "DP_SV_WRITEUNTERMINATEDSTRING "
145 "DP_TE_EXPLOSIONRGB "
147 "DP_TE_PARTICLECUBE "
148 "DP_TE_PARTICLERAIN "
149 "DP_TE_PARTICLESNOW "
151 "DP_TE_QUADEFFECTS1 "
154 "DP_TE_STANDARDEFFECTBUILTINS "
155 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
160 "KRIMZON_SV_PARSECLIENTCOMMAND "
163 "NEXUIZ_PLAYERMODEL "
165 "PRYDON_CLIENTCURSOR "
166 "TENEBRAE_GFX_DLIGHTS "
168 //"EXT_CSQC " // not ready yet
175 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.
177 setorigin (entity, origin)
180 static void VM_SV_setorigin (void)
185 VM_SAFEPARMCOUNT(2, VM_setorigin);
187 e = PRVM_G_EDICT(OFS_PARM0);
188 if (e == prog->edicts)
190 VM_Warning("setorigin: can not modify world entity\n");
193 if (e->priv.server->free)
195 VM_Warning("setorigin: can not modify free entity\n");
198 org = PRVM_G_VECTOR(OFS_PARM1);
199 VectorCopy (org, e->fields.server->origin);
200 SV_LinkEdict (e, false);
203 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
204 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
208 for (i=0 ; i<3 ; i++)
210 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
212 // set derived values
213 VectorCopy (min, e->fields.server->mins);
214 VectorCopy (max, e->fields.server->maxs);
215 VectorSubtract (max, min, e->fields.server->size);
217 SV_LinkEdict (e, false);
224 the size box is rotated by the current angle
225 LordHavoc: no it isn't...
227 setsize (entity, minvector, maxvector)
230 static void VM_SV_setsize (void)
235 VM_SAFEPARMCOUNT(3, VM_setsize);
237 e = PRVM_G_EDICT(OFS_PARM0);
238 if (e == prog->edicts)
240 VM_Warning("setsize: can not modify world entity\n");
243 if (e->priv.server->free)
245 VM_Warning("setsize: can not modify free entity\n");
248 min = PRVM_G_VECTOR(OFS_PARM1);
249 max = PRVM_G_VECTOR(OFS_PARM2);
250 SetMinMaxSize (e, min, max, false);
258 setmodel(entity, model)
261 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
262 static void VM_SV_setmodel (void)
268 VM_SAFEPARMCOUNT(2, VM_setmodel);
270 e = PRVM_G_EDICT(OFS_PARM0);
271 if (e == prog->edicts)
273 VM_Warning("setmodel: can not modify world entity\n");
276 if (e->priv.server->free)
278 VM_Warning("setmodel: can not modify free entity\n");
281 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
282 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
283 e->fields.server->modelindex = i;
289 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
290 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
292 SetMinMaxSize (e, quakemins, quakemaxs, true);
295 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
302 single print to a specific client
304 sprint(clientent, value)
307 static void VM_SV_sprint (void)
311 char string[VM_STRINGTEMP_LENGTH];
313 VM_VarString(1, string, sizeof(string));
315 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
317 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
318 // LordHavoc: div0 requested that sprintto world operate like print
325 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
327 VM_Warning("tried to centerprint to a non-client\n");
331 client = svs.clients + entnum-1;
332 if (!client->netconnection)
335 MSG_WriteChar(&client->netconnection->message,svc_print);
336 MSG_WriteString(&client->netconnection->message, string);
344 single print to a specific client
346 centerprint(clientent, value)
349 static void VM_SV_centerprint (void)
353 char string[VM_STRINGTEMP_LENGTH];
355 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
357 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
359 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
361 VM_Warning("tried to centerprint to a non-client\n");
365 client = svs.clients + entnum-1;
366 if (!client->netconnection)
369 VM_VarString(1, string, sizeof(string));
370 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
371 MSG_WriteString(&client->netconnection->message, string);
378 particle(origin, color, count)
381 static void VM_SV_particle (void)
387 VM_SAFEPARMCOUNT(4, VM_SV_particle);
389 org = PRVM_G_VECTOR(OFS_PARM0);
390 dir = PRVM_G_VECTOR(OFS_PARM1);
391 color = PRVM_G_FLOAT(OFS_PARM2);
392 count = PRVM_G_FLOAT(OFS_PARM3);
393 SV_StartParticle (org, dir, (int)color, (int)count);
403 static void VM_SV_ambientsound (void)
407 float vol, attenuation;
410 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
412 pos = PRVM_G_VECTOR (OFS_PARM0);
413 samp = PRVM_G_STRING(OFS_PARM1);
414 vol = PRVM_G_FLOAT(OFS_PARM2);
415 attenuation = PRVM_G_FLOAT(OFS_PARM3);
417 // check to see if samp was properly precached
418 soundnum = SV_SoundIndex(samp, 1);
426 // add an svc_spawnambient command to the level signon packet
429 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
431 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
433 MSG_WriteVector(&sv.signon, pos, sv.protocol);
435 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
436 MSG_WriteShort (&sv.signon, soundnum);
438 MSG_WriteByte (&sv.signon, soundnum);
440 MSG_WriteByte (&sv.signon, (int)(vol*255));
441 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
449 Each entity can have eight independant sound sources, like voice,
452 Channel 0 is an auto-allocate channel, the others override anything
453 already running on that entity/channel pair.
455 An attenuation of 0 will play full volume everywhere in the level.
456 Larger attenuations will drop off.
460 static void VM_SV_sound (void)
464 prvm_edict_t *entity;
468 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
470 entity = PRVM_G_EDICT(OFS_PARM0);
471 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
472 sample = PRVM_G_STRING(OFS_PARM2);
473 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
474 attenuation = PRVM_G_FLOAT(OFS_PARM4);
477 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
481 if (volume < 0 || volume > 255)
483 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
487 if (attenuation < 0 || attenuation > 4)
489 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
493 if (channel < 0 || channel > 7)
495 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
499 SV_StartSound (entity, channel, sample, volume, attenuation);
506 Follows the same logic as VM_SV_sound, except instead of
507 an entity, an origin for the sound is provided, and channel
508 is omitted (since no entity is being tracked).
512 static void VM_SV_pointsound(void)
519 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
521 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
522 sample = PRVM_G_STRING(OFS_PARM1);
523 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
524 attenuation = PRVM_G_FLOAT(OFS_PARM3);
526 if (volume < 0 || volume > 255)
528 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
532 if (attenuation < 0 || attenuation > 4)
534 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
538 SV_StartPointSound (org, sample, volume, attenuation);
545 Used for use tracing and shot targeting
546 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
547 if the tryents flag is set.
549 traceline (vector1, vector2, movetype, ignore)
552 static void VM_SV_traceline (void)
559 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
561 prog->xfunction->builtinsprofile += 30;
563 v1 = PRVM_G_VECTOR(OFS_PARM0);
564 v2 = PRVM_G_VECTOR(OFS_PARM1);
565 move = (int)PRVM_G_FLOAT(OFS_PARM2);
566 ent = PRVM_G_EDICT(OFS_PARM3);
568 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
569 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));
571 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
573 VM_SetTraceGlobals(&trace);
581 Used for use tracing and shot targeting
582 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
583 if the tryents flag is set.
585 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
588 // LordHavoc: added this for my own use, VERY useful, similar to traceline
589 static void VM_SV_tracebox (void)
591 float *v1, *v2, *m1, *m2;
596 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
598 prog->xfunction->builtinsprofile += 30;
600 v1 = PRVM_G_VECTOR(OFS_PARM0);
601 m1 = PRVM_G_VECTOR(OFS_PARM1);
602 m2 = PRVM_G_VECTOR(OFS_PARM2);
603 v2 = PRVM_G_VECTOR(OFS_PARM3);
604 move = (int)PRVM_G_FLOAT(OFS_PARM4);
605 ent = PRVM_G_EDICT(OFS_PARM5);
607 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
608 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));
610 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
612 VM_SetTraceGlobals(&trace);
615 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
620 vec3_t original_origin;
621 vec3_t original_velocity;
622 vec3_t original_angles;
623 vec3_t original_avelocity;
627 VectorCopy(tossent->fields.server->origin , original_origin );
628 VectorCopy(tossent->fields.server->velocity , original_velocity );
629 VectorCopy(tossent->fields.server->angles , original_angles );
630 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
632 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
633 if (val != NULL && val->_float != 0)
634 gravity = val->_float;
637 gravity *= sv_gravity.value * 0.05;
639 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
641 SV_CheckVelocity (tossent);
642 tossent->fields.server->velocity[2] -= gravity;
643 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
644 VectorScale (tossent->fields.server->velocity, 0.05, move);
645 VectorAdd (tossent->fields.server->origin, move, end);
646 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
647 VectorCopy (trace.endpos, tossent->fields.server->origin);
649 if (trace.fraction < 1)
653 VectorCopy(original_origin , tossent->fields.server->origin );
654 VectorCopy(original_velocity , tossent->fields.server->velocity );
655 VectorCopy(original_angles , tossent->fields.server->angles );
656 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
661 static void VM_SV_tracetoss (void)
665 prvm_edict_t *ignore;
667 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
669 prog->xfunction->builtinsprofile += 600;
671 ent = PRVM_G_EDICT(OFS_PARM0);
672 if (ent == prog->edicts)
674 VM_Warning("tracetoss: can not use world entity\n");
677 ignore = PRVM_G_EDICT(OFS_PARM1);
679 trace = SV_Trace_Toss (ent, ignore);
681 VM_SetTraceGlobals(&trace);
684 //============================================================================
686 static int checkpvsbytes;
687 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
689 static int VM_SV_newcheckclient (int check)
695 // cycle to the next one
697 check = bound(1, check, svs.maxclients);
698 if (check == svs.maxclients)
706 prog->xfunction->builtinsprofile++;
708 if (i == svs.maxclients+1)
710 // look up the client's edict
711 ent = PRVM_EDICT_NUM(i);
712 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
713 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
715 // found a valid client (possibly the same one again)
719 // get the PVS for the entity
720 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
722 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
723 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
732 Returns a client (or object that has a client enemy) that would be a
735 If there is more than one valid option, they are cycled each frame
737 If (self.origin + self.viewofs) is not in the PVS of the current target,
738 it is not returned at all.
743 int c_invis, c_notvis;
744 static void VM_SV_checkclient (void)
746 prvm_edict_t *ent, *self;
749 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
751 // find a new check if on a new frame
752 if (sv.time - sv.lastchecktime >= 0.1)
754 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
755 sv.lastchecktime = sv.time;
758 // return check if it might be visible
759 ent = PRVM_EDICT_NUM(sv.lastcheck);
760 if (ent->priv.server->free || ent->fields.server->health <= 0)
762 VM_RETURN_EDICT(prog->edicts);
766 // if current entity can't possibly see the check entity, return 0
767 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
768 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
769 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
772 VM_RETURN_EDICT(prog->edicts);
776 // might be able to see it
778 VM_RETURN_EDICT(ent);
781 //============================================================================
788 Sends text over to the client's execution buffer
790 stuffcmd (clientent, value, ...)
793 static void VM_SV_stuffcmd (void)
797 char string[VM_STRINGTEMP_LENGTH];
799 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
801 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
802 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
804 VM_Warning("Can't stuffcmd to a non-client\n");
808 VM_VarString(1, string, sizeof(string));
811 host_client = svs.clients + entnum-1;
812 Host_ClientCommands ("%s", string);
820 Returns a chain of entities that have origins within a spherical area
822 findradius (origin, radius)
825 static void VM_SV_findradius (void)
827 prvm_edict_t *ent, *chain;
828 vec_t radius, radius2;
829 vec3_t org, eorg, mins, maxs;
832 prvm_edict_t *touchedicts[MAX_EDICTS];
834 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
836 chain = (prvm_edict_t *)prog->edicts;
838 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
839 radius = PRVM_G_FLOAT(OFS_PARM1);
840 radius2 = radius * radius;
842 mins[0] = org[0] - (radius + 1);
843 mins[1] = org[1] - (radius + 1);
844 mins[2] = org[2] - (radius + 1);
845 maxs[0] = org[0] + (radius + 1);
846 maxs[1] = org[1] + (radius + 1);
847 maxs[2] = org[2] + (radius + 1);
848 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
849 if (numtouchedicts > MAX_EDICTS)
851 // this never happens
852 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
853 numtouchedicts = MAX_EDICTS;
855 for (i = 0;i < numtouchedicts;i++)
857 ent = touchedicts[i];
858 prog->xfunction->builtinsprofile++;
859 // Quake did not return non-solid entities but darkplaces does
860 // (note: this is the reason you can't blow up fallen zombies)
861 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
863 // LordHavoc: compare against bounding box rather than center so it
864 // doesn't miss large objects, and use DotProduct instead of Length
865 // for a major speedup
866 VectorSubtract(org, ent->fields.server->origin, eorg);
867 if (sv_gameplayfix_findradiusdistancetobox.integer)
869 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
870 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
871 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
874 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
875 if (DotProduct(eorg, eorg) < radius2)
877 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
882 VM_RETURN_EDICT(chain);
885 static void VM_SV_precache_sound (void)
887 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
888 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
891 static void VM_SV_precache_model (void)
893 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
894 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
895 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
902 float(float yaw, float dist[, settrace]) walkmove
905 static void VM_SV_walkmove (void)
914 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
916 // assume failure if it returns early
917 PRVM_G_FLOAT(OFS_RETURN) = 0;
919 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
920 if (ent == prog->edicts)
922 VM_Warning("walkmove: can not modify world entity\n");
925 if (ent->priv.server->free)
927 VM_Warning("walkmove: can not modify free entity\n");
930 yaw = PRVM_G_FLOAT(OFS_PARM0);
931 dist = PRVM_G_FLOAT(OFS_PARM1);
932 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
934 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
937 yaw = yaw*M_PI*2 / 360;
939 move[0] = cos(yaw)*dist;
940 move[1] = sin(yaw)*dist;
943 // save program state, because SV_movestep may call other progs
944 oldf = prog->xfunction;
945 oldself = prog->globals.server->self;
947 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
950 // restore program state
951 prog->xfunction = oldf;
952 prog->globals.server->self = oldself;
962 static void VM_SV_droptofloor (void)
968 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
970 // assume failure if it returns early
971 PRVM_G_FLOAT(OFS_RETURN) = 0;
973 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
974 if (ent == prog->edicts)
976 VM_Warning("droptofloor: can not modify world entity\n");
979 if (ent->priv.server->free)
981 VM_Warning("droptofloor: can not modify free entity\n");
985 VectorCopy (ent->fields.server->origin, end);
988 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
989 SV_UnstickEntity(ent);
991 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
992 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
995 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]);
996 VectorAdd(ent->fields.server->origin, offset, org);
997 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
998 VectorSubtract(trace.endpos, offset, trace.endpos);
999 if (trace.startsolid)
1001 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]);
1002 SV_UnstickEntity(ent);
1003 SV_LinkEdict (ent, false);
1004 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1005 ent->fields.server->groundentity = 0;
1006 PRVM_G_FLOAT(OFS_RETURN) = 1;
1008 else if (trace.fraction < 1)
1010 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]);
1011 VectorCopy (trace.endpos, ent->fields.server->origin);
1012 SV_UnstickEntity(ent);
1013 SV_LinkEdict (ent, false);
1014 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1015 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1016 PRVM_G_FLOAT(OFS_RETURN) = 1;
1017 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1018 ent->priv.server->suspendedinairflag = true;
1023 if (trace.fraction != 1)
1025 if (trace.fraction < 1)
1026 VectorCopy (trace.endpos, ent->fields.server->origin);
1027 SV_LinkEdict (ent, false);
1028 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1029 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1030 PRVM_G_FLOAT(OFS_RETURN) = 1;
1031 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1032 ent->priv.server->suspendedinairflag = true;
1041 void(float style, string value) lightstyle
1044 static void VM_SV_lightstyle (void)
1051 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1053 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1054 val = PRVM_G_STRING(OFS_PARM1);
1056 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1057 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1060 // change the string in sv
1061 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1063 // send message to all clients on this server
1064 if (sv.state != ss_active)
1067 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1069 if (client->active && client->netconnection)
1071 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1072 MSG_WriteChar (&client->netconnection->message,style);
1073 MSG_WriteString (&client->netconnection->message, val);
1083 static void VM_SV_checkbottom (void)
1085 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1086 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1094 static void VM_SV_pointcontents (void)
1096 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1097 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1104 Pick a vector for the player to shoot along
1105 vector aim(entity, missilespeed)
1108 static void VM_SV_aim (void)
1110 prvm_edict_t *ent, *check, *bestent;
1111 vec3_t start, dir, end, bestdir;
1114 float dist, bestdist;
1117 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1119 // assume failure if it returns early
1120 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1121 // if sv_aim is so high it can't possibly accept anything, skip out early
1122 if (sv_aim.value >= 1)
1125 ent = PRVM_G_EDICT(OFS_PARM0);
1126 if (ent == prog->edicts)
1128 VM_Warning("aim: can not use world entity\n");
1131 if (ent->priv.server->free)
1133 VM_Warning("aim: can not use free entity\n");
1136 speed = PRVM_G_FLOAT(OFS_PARM1);
1138 VectorCopy (ent->fields.server->origin, start);
1141 // try sending a trace straight
1142 VectorCopy (prog->globals.server->v_forward, dir);
1143 VectorMA (start, 2048, dir, end);
1144 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1145 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1146 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1148 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1153 // try all possible entities
1154 VectorCopy (dir, bestdir);
1155 bestdist = sv_aim.value;
1158 check = PRVM_NEXT_EDICT(prog->edicts);
1159 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1161 prog->xfunction->builtinsprofile++;
1162 if (check->fields.server->takedamage != DAMAGE_AIM)
1166 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1167 continue; // don't aim at teammate
1168 for (j=0 ; j<3 ; j++)
1169 end[j] = check->fields.server->origin[j]
1170 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1171 VectorSubtract (end, start, dir);
1172 VectorNormalize (dir);
1173 dist = DotProduct (dir, prog->globals.server->v_forward);
1174 if (dist < bestdist)
1175 continue; // to far to turn
1176 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1177 if (tr.ent == check)
1178 { // can shoot at this one
1186 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1187 dist = DotProduct (dir, prog->globals.server->v_forward);
1188 VectorScale (prog->globals.server->v_forward, dist, end);
1190 VectorNormalize (end);
1191 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1195 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1200 ===============================================================================
1204 ===============================================================================
1207 #define MSG_BROADCAST 0 // unreliable to all
1208 #define MSG_ONE 1 // reliable to one (msg_entity)
1209 #define MSG_ALL 2 // reliable to all
1210 #define MSG_INIT 3 // write to the init string
1211 #define MSG_ENTITY 5
1213 sizebuf_t *WriteDest (void)
1219 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1223 return &sv.datagram;
1226 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1227 entnum = PRVM_NUM_FOR_EDICT(ent);
1228 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1230 VM_Warning ("WriteDest: tried to write to non-client\n");
1231 return &sv.reliable_datagram;
1234 return &svs.clients[entnum-1].netconnection->message;
1237 VM_Warning ("WriteDest: bad destination\n");
1239 return &sv.reliable_datagram;
1245 return sv.writeentitiestoclient_msg;
1251 static void VM_SV_WriteByte (void)
1253 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1254 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1257 static void VM_SV_WriteChar (void)
1259 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1260 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1263 static void VM_SV_WriteShort (void)
1265 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1266 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1269 static void VM_SV_WriteLong (void)
1271 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1272 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1275 static void VM_SV_WriteAngle (void)
1277 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1278 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1281 static void VM_SV_WriteCoord (void)
1283 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1284 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1287 static void VM_SV_WriteString (void)
1289 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1290 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1293 static void VM_SV_WriteUnterminatedString (void)
1295 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1296 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1300 static void VM_SV_WriteEntity (void)
1302 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1303 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1306 // writes a picture as at most size bytes of data
1308 // IMGNAME \0 SIZE(short) IMGDATA
1309 // if failed to read/compress:
1311 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1312 static void VM_SV_WritePicture (void)
1314 const char *imgname;
1318 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1320 imgname = PRVM_G_STRING(OFS_PARM1);
1321 size = PRVM_G_FLOAT(OFS_PARM2);
1325 MSG_WriteString(WriteDest(), imgname);
1326 if(Image_Compress(imgname, size, &buf, &size))
1329 MSG_WriteShort(WriteDest(), size);
1330 SZ_Write(WriteDest(), buf, size);
1335 MSG_WriteShort(WriteDest(), 0);
1339 //////////////////////////////////////////////////////////
1341 static void VM_SV_makestatic (void)
1346 // allow 0 parameters due to an id1 qc bug in which this function is used
1347 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1348 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1350 if (prog->argc >= 1)
1351 ent = PRVM_G_EDICT(OFS_PARM0);
1353 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1354 if (ent == prog->edicts)
1356 VM_Warning("makestatic: can not modify world entity\n");
1359 if (ent->priv.server->free)
1361 VM_Warning("makestatic: can not modify free entity\n");
1366 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1371 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1372 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1373 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1375 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1377 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1378 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1379 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1383 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1384 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1385 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1388 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1389 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1390 for (i=0 ; i<3 ; i++)
1392 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1393 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1396 // throw the entity away now
1400 //=============================================================================
1407 static void VM_SV_setspawnparms (void)
1413 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1415 ent = PRVM_G_EDICT(OFS_PARM0);
1416 i = PRVM_NUM_FOR_EDICT(ent);
1417 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1419 Con_Print("tried to setspawnparms on a non-client\n");
1423 // copy spawn parms out of the client_t
1424 client = svs.clients + i-1;
1425 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1426 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1433 Returns a color vector indicating the lighting at the requested point.
1435 (Internal Operation note: actually measures the light beneath the point, just like
1436 the model lighting on the client)
1441 static void VM_SV_getlight (void)
1443 vec3_t ambientcolor, diffusecolor, diffusenormal;
1445 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1446 p = PRVM_G_VECTOR(OFS_PARM0);
1447 VectorClear(ambientcolor);
1448 VectorClear(diffusecolor);
1449 VectorClear(diffusenormal);
1450 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1451 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1452 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1457 unsigned char type; // 1/2/8 or other value if isn't used
1461 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1462 static int vm_customstats_last;
1464 void VM_CustomStats_Clear (void)
1468 Z_Free(vm_customstats);
1469 vm_customstats = NULL;
1470 vm_customstats_last = -1;
1474 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1482 for(i=0; i<vm_customstats_last+1 ;i++)
1484 if(!vm_customstats[i].type)
1486 switch(vm_customstats[i].type)
1488 //string as 16 bytes
1491 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1492 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1493 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1494 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1495 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1497 //float field sent as-is
1499 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1501 //integer value of float field
1503 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1511 // void(float index, float type, .void field) SV_AddStat = #232;
1512 // Set up an auto-sent player stat.
1513 // Client's get thier own fields sent to them. Index may not be less than 32.
1514 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1515 // 1: string (4 stats carrying a total of 16 charactures)
1516 // 2: float (one stat, float converted to an integer for transportation)
1517 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1518 static void VM_SV_AddStat (void)
1523 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1527 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1530 VM_Warning("PF_SV_AddStat: not enough memory\n");
1534 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1535 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1536 off = PRVM_G_INT (OFS_PARM2);
1541 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1544 if(i >= (MAX_CL_STATS-32))
1546 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1549 if(i > (MAX_CL_STATS-32-4) && type == 1)
1551 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1554 vm_customstats[i].type = type;
1555 vm_customstats[i].fieldoffset = off;
1556 if(vm_customstats_last < i)
1557 vm_customstats_last = i;
1564 copies data from one entity to another
1566 copyentity(src, dst)
1569 static void VM_SV_copyentity (void)
1571 prvm_edict_t *in, *out;
1572 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1573 in = PRVM_G_EDICT(OFS_PARM0);
1574 if (in == prog->edicts)
1576 VM_Warning("copyentity: can not read world entity\n");
1579 if (in->priv.server->free)
1581 VM_Warning("copyentity: can not read free entity\n");
1584 out = PRVM_G_EDICT(OFS_PARM1);
1585 if (out == prog->edicts)
1587 VM_Warning("copyentity: can not modify world entity\n");
1590 if (out->priv.server->free)
1592 VM_Warning("copyentity: can not modify free entity\n");
1595 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1596 SV_LinkEdict(out, false);
1604 sets the color of a client and broadcasts the update to all connected clients
1606 setcolor(clientent, value)
1609 static void VM_SV_setcolor (void)
1615 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1616 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1617 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1619 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1621 Con_Print("tried to setcolor a non-client\n");
1625 client = svs.clients + entnum-1;
1628 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1630 client->edict->fields.server->team = (i & 15) + 1;
1633 if (client->old_colors != client->colors)
1635 client->old_colors = client->colors;
1636 // send notification to all clients
1637 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1638 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1639 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1647 effect(origin, modelname, startframe, framecount, framerate)
1650 static void VM_SV_effect (void)
1654 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1655 s = PRVM_G_STRING(OFS_PARM1);
1658 VM_Warning("effect: no model specified\n");
1662 i = SV_ModelIndex(s, 1);
1665 VM_Warning("effect: model not precached\n");
1669 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1671 VM_Warning("effect: framecount < 1\n");
1675 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1677 VM_Warning("effect: framerate < 1\n");
1681 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));
1684 static void VM_SV_te_blood (void)
1686 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1687 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1689 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1690 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1692 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1693 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1696 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1697 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1698 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1700 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1701 SV_FlushBroadcastMessages();
1704 static void VM_SV_te_bloodshower (void)
1706 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1707 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1709 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1710 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1722 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1723 SV_FlushBroadcastMessages();
1726 static void VM_SV_te_explosionrgb (void)
1728 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1729 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1730 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1732 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1733 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1734 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1736 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1737 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1738 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1739 SV_FlushBroadcastMessages();
1742 static void VM_SV_te_particlecube (void)
1744 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1745 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1747 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1748 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1750 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1751 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1752 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1754 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1762 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1764 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1765 // gravity true/false
1766 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1769 SV_FlushBroadcastMessages();
1772 static void VM_SV_te_particlerain (void)
1774 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1775 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1777 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1778 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1780 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1781 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1782 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1784 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1785 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1786 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1792 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1794 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1795 SV_FlushBroadcastMessages();
1798 static void VM_SV_te_particlesnow (void)
1800 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1801 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1803 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1804 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1816 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1818 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1820 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1821 SV_FlushBroadcastMessages();
1824 static void VM_SV_te_spark (void)
1826 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1827 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1829 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1830 MSG_WriteByte(&sv.datagram, TE_SPARK);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1836 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1837 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1838 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1840 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1841 SV_FlushBroadcastMessages();
1844 static void VM_SV_te_gunshotquad (void)
1846 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1847 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1848 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1850 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1851 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1853 SV_FlushBroadcastMessages();
1856 static void VM_SV_te_spikequad (void)
1858 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1859 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1860 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1865 SV_FlushBroadcastMessages();
1868 static void VM_SV_te_superspikequad (void)
1870 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1871 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1872 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1877 SV_FlushBroadcastMessages();
1880 static void VM_SV_te_explosionquad (void)
1882 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1883 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1884 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1889 SV_FlushBroadcastMessages();
1892 static void VM_SV_te_smallflash (void)
1894 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1895 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1896 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1901 SV_FlushBroadcastMessages();
1904 static void VM_SV_te_customflash (void)
1906 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1907 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1909 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1910 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1916 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1918 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1920 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1921 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1922 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1923 SV_FlushBroadcastMessages();
1926 static void VM_SV_te_gunshot (void)
1928 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1929 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1930 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1935 SV_FlushBroadcastMessages();
1938 static void VM_SV_te_spike (void)
1940 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1941 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1942 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1946 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1947 SV_FlushBroadcastMessages();
1950 static void VM_SV_te_superspike (void)
1952 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1953 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1954 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1959 SV_FlushBroadcastMessages();
1962 static void VM_SV_te_explosion (void)
1964 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1965 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1966 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1971 SV_FlushBroadcastMessages();
1974 static void VM_SV_te_tarexplosion (void)
1976 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1977 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1978 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1982 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1983 SV_FlushBroadcastMessages();
1986 static void VM_SV_te_wizspike (void)
1988 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1989 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1990 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1995 SV_FlushBroadcastMessages();
1998 static void VM_SV_te_knightspike (void)
2000 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2001 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2002 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2007 SV_FlushBroadcastMessages();
2010 static void VM_SV_te_lavasplash (void)
2012 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2013 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2014 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2019 SV_FlushBroadcastMessages();
2022 static void VM_SV_te_teleport (void)
2024 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2025 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2026 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2028 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2029 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2031 SV_FlushBroadcastMessages();
2034 static void VM_SV_te_explosion2 (void)
2036 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2037 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2038 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2040 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2041 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2042 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2044 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2045 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2046 SV_FlushBroadcastMessages();
2049 static void VM_SV_te_lightning1 (void)
2051 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2052 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2053 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2055 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2058 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2059 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2061 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2063 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2064 SV_FlushBroadcastMessages();
2067 static void VM_SV_te_lightning2 (void)
2069 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2070 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2071 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2073 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2075 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2076 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2077 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2079 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2080 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2081 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2082 SV_FlushBroadcastMessages();
2085 static void VM_SV_te_lightning3 (void)
2087 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2088 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2089 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2091 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2093 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2094 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2095 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2100 SV_FlushBroadcastMessages();
2103 static void VM_SV_te_beam (void)
2105 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2106 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2107 MSG_WriteByte(&sv.datagram, TE_BEAM);
2109 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2111 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2112 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2113 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2115 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2116 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2117 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2118 SV_FlushBroadcastMessages();
2121 static void VM_SV_te_plasmaburn (void)
2123 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2124 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2125 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2126 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2127 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2128 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2129 SV_FlushBroadcastMessages();
2132 static void VM_SV_te_flamejet (void)
2134 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2135 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2136 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2138 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2139 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2140 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2142 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2143 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2144 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2146 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2147 SV_FlushBroadcastMessages();
2150 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2153 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2155 bestdist = 1000000000;
2157 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2159 // clip original point to each triangle of the surface and find the
2160 // triangle that is closest
2161 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2162 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2163 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2164 TriangleNormal(v[0], v[1], v[2], facenormal);
2165 VectorNormalize(facenormal);
2166 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2167 VectorMA(p, offsetdist, facenormal, temp);
2168 for (j = 0, k = 2;j < 3;k = j, j++)
2170 VectorSubtract(v[k], v[j], edgenormal);
2171 CrossProduct(edgenormal, facenormal, sidenormal);
2172 VectorNormalize(sidenormal);
2173 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2175 VectorMA(temp, offsetdist, sidenormal, temp);
2177 dist = VectorDistance2(temp, p);
2178 if (bestdist > dist)
2181 VectorCopy(temp, out);
2186 static dp_model_t *getmodel(prvm_edict_t *ed)
2189 if (!ed || ed->priv.server->free)
2191 modelindex = (int)ed->fields.server->modelindex;
2192 if (modelindex < 1 || modelindex >= MAX_MODELS)
2194 return sv.models[modelindex];
2197 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2199 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2201 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2205 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2206 static void VM_SV_getsurfacenumpoints(void)
2209 msurface_t *surface;
2210 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2211 // return 0 if no such surface
2212 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2214 PRVM_G_FLOAT(OFS_RETURN) = 0;
2218 // note: this (incorrectly) assumes it is a simple polygon
2219 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2221 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2222 static void VM_SV_getsurfacepoint(void)
2226 msurface_t *surface;
2228 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2229 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2230 ed = PRVM_G_EDICT(OFS_PARM0);
2231 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2233 // note: this (incorrectly) assumes it is a simple polygon
2234 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2235 if (pointnum < 0 || pointnum >= surface->num_vertices)
2237 // FIXME: implement rotation/scaling
2238 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2240 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2241 // float SPA_POSITION = 0;
2242 // float SPA_S_AXIS = 1;
2243 // float SPA_T_AXIS = 2;
2244 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2245 // float SPA_TEXCOORDS0 = 4;
2246 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2247 // float SPA_LIGHTMAP0_COLOR = 6;
2248 static void VM_SV_getsurfacepointattribute(void)
2252 msurface_t *surface;
2256 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2257 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2258 ed = PRVM_G_EDICT(OFS_PARM0);
2259 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2261 // note: this (incorrectly) assumes it is a simple polygon
2262 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2263 if (pointnum < 0 || pointnum >= surface->num_vertices)
2265 // FIXME: implement rotation/scaling
2266 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2268 switch( attributetype ) {
2269 // float SPA_POSITION = 0;
2271 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2273 // float SPA_S_AXIS = 1;
2275 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2277 // float SPA_T_AXIS = 2;
2279 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2281 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2283 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2285 // float SPA_TEXCOORDS0 = 4;
2287 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2288 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2289 ret[0] = texcoord[0];
2290 ret[1] = texcoord[1];
2294 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2296 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2297 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2298 ret[0] = texcoord[0];
2299 ret[1] = texcoord[1];
2303 // float SPA_LIGHTMAP0_COLOR = 6;
2305 // ignore alpha for now..
2306 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2309 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2313 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2314 static void VM_SV_getsurfacenormal(void)
2317 msurface_t *surface;
2319 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2320 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2321 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2323 // FIXME: implement rotation/scaling
2324 // note: this (incorrectly) assumes it is a simple polygon
2325 // note: this only returns the first triangle, so it doesn't work very
2326 // well for curved surfaces or arbitrary meshes
2327 TriangleNormal((model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex), (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 3, (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
2328 VectorNormalize(normal);
2329 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2331 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2332 static void VM_SV_getsurfacetexture(void)
2335 msurface_t *surface;
2336 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2337 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2338 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2340 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2342 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2343 static void VM_SV_getsurfacenearpoint(void)
2345 int surfacenum, best;
2347 vec_t dist, bestdist;
2350 msurface_t *surface;
2352 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2353 PRVM_G_FLOAT(OFS_RETURN) = -1;
2354 ed = PRVM_G_EDICT(OFS_PARM0);
2355 point = PRVM_G_VECTOR(OFS_PARM1);
2357 if (!ed || ed->priv.server->free)
2359 model = getmodel(ed);
2360 if (!model || !model->num_surfaces)
2363 // FIXME: implement rotation/scaling
2364 VectorSubtract(point, ed->fields.server->origin, p);
2366 bestdist = 1000000000;
2367 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2369 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2370 // first see if the nearest point on the surface's box is closer than the previous match
2371 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2372 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2373 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2374 dist = VectorLength2(clipped);
2375 if (dist < bestdist)
2377 // it is, check the nearest point on the actual geometry
2378 clippointtosurface(model, surface, p, clipped);
2379 VectorSubtract(clipped, p, clipped);
2380 dist += VectorLength2(clipped);
2381 if (dist < bestdist)
2383 // that's closer too, store it as the best match
2389 PRVM_G_FLOAT(OFS_RETURN) = best;
2391 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2392 static void VM_SV_getsurfaceclippedpoint(void)
2396 msurface_t *surface;
2398 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2399 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2400 ed = PRVM_G_EDICT(OFS_PARM0);
2401 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2403 // FIXME: implement rotation/scaling
2404 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2405 clippointtosurface(model, surface, p, out);
2406 // FIXME: implement rotation/scaling
2407 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2410 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2411 //this function originally written by KrimZon, made shorter by LordHavoc
2412 static void VM_SV_clientcommand (void)
2414 client_t *temp_client;
2416 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2418 //find client for this entity
2419 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2420 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2422 Con_Print("PF_clientcommand: entity is not a client\n");
2426 temp_client = host_client;
2427 host_client = svs.clients + i;
2428 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2429 host_client = temp_client;
2432 //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)
2433 static void VM_SV_setattachment (void)
2435 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2436 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2437 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2441 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2443 if (e == prog->edicts)
2445 VM_Warning("setattachment: can not modify world entity\n");
2448 if (e->priv.server->free)
2450 VM_Warning("setattachment: can not modify free entity\n");
2454 if (tagentity == NULL)
2455 tagentity = prog->edicts;
2457 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2459 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2461 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2464 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2466 modelindex = (int)tagentity->fields.server->modelindex;
2467 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2469 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2471 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);
2474 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));
2478 /////////////////////////////////////////
2479 // DP_MD3_TAGINFO extension coded by VorteX
2481 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2486 i = (int)e->fields.server->modelindex;
2487 if (i < 1 || i >= MAX_MODELS)
2489 model = sv.models[i];
2491 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2494 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2496 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2500 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);
2502 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale * cl_viewmodel_scale.value);
2505 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2511 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2512 && (model = sv.models[(int)ent->fields.server->modelindex])
2513 && model->animscenes)
2515 // if model has wrong frame, engine automatically switches to model first frame
2516 frame = (int)ent->fields.server->frame;
2517 if (frame < 0 || frame >= model->numframes)
2519 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2521 *out = identitymatrix;
2525 // Warnings/errors code:
2526 // 0 - normal (everything all-right)
2529 // 3 - null or non-precached model
2530 // 4 - no tags with requested index
2531 // 5 - runaway loop at attachment chain
2532 extern cvar_t cl_bob;
2533 extern cvar_t cl_bobcycle;
2534 extern cvar_t cl_bobup;
2535 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2539 int modelindex, attachloop;
2540 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2543 *out = identitymatrix; // warnings and errors return identical matrix
2545 if (ent == prog->edicts)
2547 if (ent->priv.server->free)
2550 modelindex = (int)ent->fields.server->modelindex;
2551 if (modelindex <= 0 || modelindex > MAX_MODELS)
2554 model = sv.models[modelindex];
2556 tagmatrix = identitymatrix;
2557 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2561 if (attachloop >= 256) // prevent runaway looping
2563 // apply transformation by child's tagindex on parent entity and then
2564 // by parent entity itself
2565 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2566 if (ret && attachloop == 0)
2568 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2569 SV_GetEntityMatrix(ent, &entitymatrix, false);
2570 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2571 // next iteration we process the parent entity
2572 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2574 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2575 ent = PRVM_EDICT_NUM(val->edict);
2582 // RENDER_VIEWMODEL magic
2583 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2585 Matrix4x4_Copy(&tagmatrix, out);
2586 ent = PRVM_EDICT_NUM(val->edict);
2588 SV_GetEntityMatrix(ent, &entitymatrix, true);
2589 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2592 // Cl_bob, ported from rendering code
2593 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2596 // LordHavoc: this code is *weird*, but not replacable (I think it
2597 // should be done in QC on the server, but oh well, quake is quake)
2598 // LordHavoc: figured out bobup: the time at which the sin is at 180
2599 // degrees (which allows lengthening or squishing the peak or valley)
2600 cycle = sv.time/cl_bobcycle.value;
2601 cycle -= (int)cycle;
2602 if (cycle < cl_bobup.value)
2603 cycle = sin(M_PI * cycle / cl_bobup.value);
2605 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2606 // bob is proportional to velocity in the xy plane
2607 // (don't count Z, or jumping messes it up)
2608 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;
2609 bob = bob*0.3 + bob*0.7*cycle;
2610 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2617 //float(entity ent, string tagname) gettagindex;
2619 static void VM_SV_gettagindex (void)
2622 const char *tag_name;
2623 int modelindex, tag_index;
2625 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2627 ent = PRVM_G_EDICT(OFS_PARM0);
2628 tag_name = PRVM_G_STRING(OFS_PARM1);
2630 if (ent == prog->edicts)
2632 VM_Warning("gettagindex: can't affect world entity\n");
2635 if (ent->priv.server->free)
2637 VM_Warning("gettagindex: can't affect free entity\n");
2641 modelindex = (int)ent->fields.server->modelindex;
2643 if (modelindex <= 0 || modelindex > MAX_MODELS)
2644 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2647 tag_index = SV_GetTagIndex(ent, tag_name);
2649 if(developer.integer >= 100)
2650 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2652 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2655 //vector(entity ent, float tagindex) gettaginfo;
2656 static void VM_SV_gettaginfo (void)
2660 matrix4x4_t tag_matrix;
2663 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2665 e = PRVM_G_EDICT(OFS_PARM0);
2666 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2668 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2669 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2674 VM_Warning("gettagindex: can't affect world entity\n");
2677 VM_Warning("gettagindex: can't affect free entity\n");
2680 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2683 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2686 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2691 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2692 static void VM_SV_dropclient (void)
2695 client_t *oldhostclient;
2696 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2697 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2698 if (clientnum < 0 || clientnum >= svs.maxclients)
2700 VM_Warning("dropclient: not a client\n");
2703 if (!svs.clients[clientnum].active)
2705 VM_Warning("dropclient: that client slot is not connected\n");
2708 oldhostclient = host_client;
2709 host_client = svs.clients + clientnum;
2710 SV_DropClient(false);
2711 host_client = oldhostclient;
2714 //entity() spawnclient (DP_SV_BOTCLIENT)
2715 static void VM_SV_spawnclient (void)
2719 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2720 prog->xfunction->builtinsprofile += 2;
2722 for (i = 0;i < svs.maxclients;i++)
2724 if (!svs.clients[i].active)
2726 prog->xfunction->builtinsprofile += 100;
2727 SV_ConnectClient (i, NULL);
2728 // this has to be set or else ClientDisconnect won't be called
2729 // we assume the qc will call ClientConnect...
2730 svs.clients[i].clientconnectcalled = true;
2731 ed = PRVM_EDICT_NUM(i + 1);
2735 VM_RETURN_EDICT(ed);
2738 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2739 static void VM_SV_clienttype (void)
2742 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2743 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2744 if (clientnum < 0 || clientnum >= svs.maxclients)
2745 PRVM_G_FLOAT(OFS_RETURN) = 3;
2746 else if (!svs.clients[clientnum].active)
2747 PRVM_G_FLOAT(OFS_RETURN) = 0;
2748 else if (svs.clients[clientnum].netconnection)
2749 PRVM_G_FLOAT(OFS_RETURN) = 1;
2751 PRVM_G_FLOAT(OFS_RETURN) = 2;
2758 string(string key) serverkey
2761 void VM_SV_serverkey(void)
2763 char string[VM_STRINGTEMP_LENGTH];
2764 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2765 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2766 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2769 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2770 static void VM_SV_setmodelindex (void)
2775 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2777 e = PRVM_G_EDICT(OFS_PARM0);
2778 if (e == prog->edicts)
2780 VM_Warning("setmodelindex: can not modify world entity\n");
2783 if (e->priv.server->free)
2785 VM_Warning("setmodelindex: can not modify free entity\n");
2788 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2789 if (i <= 0 || i > MAX_MODELS)
2791 VM_Warning("setmodelindex: invalid modelindex\n");
2794 if (!sv.model_precache[i][0])
2796 VM_Warning("setmodelindex: model not precached\n");
2800 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2801 e->fields.server->modelindex = i;
2807 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2808 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2810 SetMinMaxSize (e, quakemins, quakemaxs, true);
2813 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2816 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2817 static void VM_SV_modelnameforindex (void)
2820 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2822 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2824 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2825 if (i <= 0 || i > MAX_MODELS)
2827 VM_Warning("modelnameforindex: invalid modelindex\n");
2830 if (!sv.model_precache[i][0])
2832 VM_Warning("modelnameforindex: model not precached\n");
2836 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2839 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2840 static void VM_SV_particleeffectnum (void)
2843 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2844 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2847 PRVM_G_FLOAT(OFS_RETURN) = i;
2850 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2851 static void VM_SV_trailparticles (void)
2853 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2855 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2858 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2859 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2860 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2861 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2862 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2863 SV_FlushBroadcastMessages();
2866 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2867 static void VM_SV_pointparticles (void)
2869 int effectnum, count;
2871 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2873 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2876 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2877 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2878 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2879 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2880 if (count == 1 && !VectorLength2(vel))
2883 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2884 MSG_WriteShort(&sv.datagram, effectnum);
2885 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2889 // 1+2+12+12+2=29 bytes
2890 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2891 MSG_WriteShort(&sv.datagram, effectnum);
2892 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2893 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2894 MSG_WriteShort(&sv.datagram, count);
2897 SV_FlushBroadcastMessages();
2900 prvm_builtin_t vm_sv_builtins[] = {
2901 NULL, // #0 NULL function (not callable) (QUAKE)
2902 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2903 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2904 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2905 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2906 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2907 VM_break, // #6 void() break (QUAKE)
2908 VM_random, // #7 float() random (QUAKE)
2909 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2910 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2911 VM_error, // #10 void(string e) error (QUAKE)
2912 VM_objerror, // #11 void(string e) objerror (QUAKE)
2913 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2914 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2915 VM_spawn, // #14 entity() spawn (QUAKE)
2916 VM_remove, // #15 void(entity e) remove (QUAKE)
2917 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2918 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2919 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2920 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2921 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2922 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2923 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2924 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2925 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2926 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2927 VM_ftos, // #26 string(float f) ftos (QUAKE)
2928 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2929 VM_coredump, // #28 void() coredump (QUAKE)
2930 VM_traceon, // #29 void() traceon (QUAKE)
2931 VM_traceoff, // #30 void() traceoff (QUAKE)
2932 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2933 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2934 NULL, // #33 (QUAKE)
2935 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2936 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2937 VM_rint, // #36 float(float v) rint (QUAKE)
2938 VM_floor, // #37 float(float v) floor (QUAKE)
2939 VM_ceil, // #38 float(float v) ceil (QUAKE)
2940 NULL, // #39 (QUAKE)
2941 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2942 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2943 NULL, // #42 (QUAKE)
2944 VM_fabs, // #43 float(float f) fabs (QUAKE)
2945 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2946 VM_cvar, // #45 float(string s) cvar (QUAKE)
2947 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2948 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2949 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2950 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2951 NULL, // #50 (QUAKE)
2952 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2953 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2954 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2955 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2956 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2957 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2958 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2959 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2960 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2961 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2962 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2963 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2964 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2965 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2966 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2967 NULL, // #66 (QUAKE)
2968 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2969 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2970 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2971 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2972 NULL, // #71 (QUAKE)
2973 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2974 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2975 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2976 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2977 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2978 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2979 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2980 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2981 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2982 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2983 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2984 NULL, // #83 (QUAKE)
2985 NULL, // #84 (QUAKE)
2986 NULL, // #85 (QUAKE)
2987 NULL, // #86 (QUAKE)
2988 NULL, // #87 (QUAKE)
2989 NULL, // #88 (QUAKE)
2990 NULL, // #89 (QUAKE)
2991 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2992 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2993 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2994 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2995 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2996 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2997 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2998 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2999 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3000 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3001 // FrikaC and Telejano range #100-#199
3012 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3013 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3014 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3015 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3016 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3017 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3018 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3019 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3020 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3021 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3102 // FTEQW range #200-#299
3121 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3124 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3125 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3126 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3127 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3128 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3129 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3130 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3131 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3132 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3133 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3135 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3203 // CSQC range #300-#399
3204 NULL, // #300 void() clearscene (EXT_CSQC)
3205 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3206 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3207 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3208 NULL, // #304 void() renderscene (EXT_CSQC)
3209 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3210 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3211 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3212 NULL, // #308 void() R_EndPolygon
3214 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3215 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3219 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3220 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3221 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3222 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3223 NULL, // #319 void(string name) freepic (EXT_CSQC)
3224 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3225 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3226 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3227 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3228 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3229 NULL, // #325 void(void) drawresetcliparea
3234 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3235 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3236 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3237 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3238 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3239 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3240 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3241 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3242 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3243 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3244 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3245 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3246 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3247 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3248 NULL, // #344 vector() getmousepos (EXT_CSQC)
3249 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3250 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3251 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3252 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3253 NULL, // #349 float() isdemo (EXT_CSQC)
3254 VM_isserver, // #350 float() isserver (EXT_CSQC)
3255 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3256 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3257 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3258 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3264 NULL, // #360 float() readbyte (EXT_CSQC)
3265 NULL, // #361 float() readchar (EXT_CSQC)
3266 NULL, // #362 float() readshort (EXT_CSQC)
3267 NULL, // #363 float() readlong (EXT_CSQC)
3268 NULL, // #364 float() readcoord (EXT_CSQC)
3269 NULL, // #365 float() readangle (EXT_CSQC)
3270 NULL, // #366 string() readstring (EXT_CSQC)
3271 NULL, // #367 float() readfloat (EXT_CSQC)
3304 // LordHavoc's range #400-#499
3305 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3306 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3307 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3308 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3309 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3310 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3311 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3312 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3313 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)
3314 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3315 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3316 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3317 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3318 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3319 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3320 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3321 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3322 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3323 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3324 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3325 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3326 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3327 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3328 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3329 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3330 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3331 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3332 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3333 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3334 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3335 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3336 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3337 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3338 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3339 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3340 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3341 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3342 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3343 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3344 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3345 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3346 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3347 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3348 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3349 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3350 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3351 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3352 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3353 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3354 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3355 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3356 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3357 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3358 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3359 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3360 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3361 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3362 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3364 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3365 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3366 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3367 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3368 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3369 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3370 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3371 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3372 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3373 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3374 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3376 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3377 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3378 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3379 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3380 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3381 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3382 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3383 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3384 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3385 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3386 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3387 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3388 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3389 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3390 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3391 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3399 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3400 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3401 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3402 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3403 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3404 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3405 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3406 VM_SV_WritePicture, // #501
3408 VM_whichpack, // #503 string(string) whichpack = #503;
3415 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3416 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3417 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3418 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3419 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3420 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3421 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3427 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3429 void VM_SV_Cmd_Init(void)
3434 void VM_SV_Cmd_Reset(void)
3436 if(prog->funcoffsets.SV_Shutdown)
3438 func_t s = prog->funcoffsets.SV_Shutdown;
3439 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3440 PRVM_ExecuteProgram(s,"SV_Shutdown() required");