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 "
65 "DP_QC_CVAR_DESCRIPTION "
72 "DP_QC_FINDCHAINFLAGS "
73 "DP_QC_FINDCHAINFLOAT "
79 "DP_QC_GETSURFACEPOINTATTRIBUTE "
82 "DP_QC_MULTIPLETEMPSTRINGS "
83 "DP_QC_NUM_FOR_EDICT "
85 "DP_QC_SINCOSSQRTPOW "
87 "DP_QC_STRINGBUFFERS "
88 "DP_QC_STRINGBUFFERS_CVARLIST "
89 "DP_QC_STRINGCOLORFUNCTIONS "
90 "DP_QC_STRING_CASE_FUNCTIONS "
92 "DP_QC_TOKENIZEBYSEPARATOR "
93 "DP_QC_TOKENIZE_CONSOLE "
96 "DP_QC_TRACE_MOVETYPE_HITMODEL "
97 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
98 "DP_QC_UNLIMITEDTEMPSTRINGS "
101 "DP_QC_VECTOANGLES_WITH_ROLL "
102 "DP_QC_VECTORVECTORS "
109 "DP_SND_DIRECTIONLESSATTNNONE "
116 "DP_SV_CLIENTCOLORS "
119 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
120 "DP_SV_DRAWONLYTOCLIENT "
123 "DP_SV_ENTITYCONTENTSTRANSITION "
124 "DP_SV_MODELFLAGS_AS_EFFECTS "
125 "DP_SV_MOVETYPESTEP_LANDEVENT "
127 "DP_SV_NODRAWTOCLIENT "
128 "DP_SV_ONENTITYNOSPAWNFUNCTION "
129 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
131 "DP_SV_PLAYERPHYSICS "
132 "DP_SV_POINTPARTICLES "
134 "DP_SV_PRECACHEANYTIME "
138 "DP_SV_ROTATINGBMODEL "
142 "DP_SV_SPAWNFUNC_PREFIX "
143 "DP_SV_WRITEPICTURE "
144 "DP_SV_WRITEUNTERMINATEDSTRING "
148 "DP_TE_EXPLOSIONRGB "
150 "DP_TE_PARTICLECUBE "
151 "DP_TE_PARTICLERAIN "
152 "DP_TE_PARTICLESNOW "
154 "DP_TE_QUADEFFECTS1 "
157 "DP_TE_STANDARDEFFECTBUILTINS "
158 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
163 "KRIMZON_SV_PARSECLIENTCOMMAND "
166 "NEXUIZ_PLAYERMODEL "
168 "PRYDON_CLIENTCURSOR "
169 "TENEBRAE_GFX_DLIGHTS "
171 //"EXT_CSQC " // not ready yet
178 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.
180 setorigin (entity, origin)
183 static void VM_SV_setorigin (void)
188 VM_SAFEPARMCOUNT(2, VM_setorigin);
190 e = PRVM_G_EDICT(OFS_PARM0);
191 if (e == prog->edicts)
193 VM_Warning("setorigin: can not modify world entity\n");
196 if (e->priv.server->free)
198 VM_Warning("setorigin: can not modify free entity\n");
201 org = PRVM_G_VECTOR(OFS_PARM1);
202 VectorCopy (org, e->fields.server->origin);
203 SV_LinkEdict (e, false);
206 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
207 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
211 for (i=0 ; i<3 ; i++)
213 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
215 // set derived values
216 VectorCopy (min, e->fields.server->mins);
217 VectorCopy (max, e->fields.server->maxs);
218 VectorSubtract (max, min, e->fields.server->size);
220 SV_LinkEdict (e, false);
227 the size box is rotated by the current angle
228 LordHavoc: no it isn't...
230 setsize (entity, minvector, maxvector)
233 static void VM_SV_setsize (void)
238 VM_SAFEPARMCOUNT(3, VM_setsize);
240 e = PRVM_G_EDICT(OFS_PARM0);
241 if (e == prog->edicts)
243 VM_Warning("setsize: can not modify world entity\n");
246 if (e->priv.server->free)
248 VM_Warning("setsize: can not modify free entity\n");
251 min = PRVM_G_VECTOR(OFS_PARM1);
252 max = PRVM_G_VECTOR(OFS_PARM2);
253 SetMinMaxSize (e, min, max, false);
261 setmodel(entity, model)
264 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
265 static void VM_SV_setmodel (void)
271 VM_SAFEPARMCOUNT(2, VM_setmodel);
273 e = PRVM_G_EDICT(OFS_PARM0);
274 if (e == prog->edicts)
276 VM_Warning("setmodel: can not modify world entity\n");
279 if (e->priv.server->free)
281 VM_Warning("setmodel: can not modify free entity\n");
284 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
285 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
286 e->fields.server->modelindex = i;
292 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
293 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
295 SetMinMaxSize (e, quakemins, quakemaxs, true);
298 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
305 single print to a specific client
307 sprint(clientent, value)
310 static void VM_SV_sprint (void)
314 char string[VM_STRINGTEMP_LENGTH];
316 VM_VarString(1, string, sizeof(string));
318 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
320 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
321 // LordHavoc: div0 requested that sprintto world operate like print
328 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
330 VM_Warning("tried to centerprint to a non-client\n");
334 client = svs.clients + entnum-1;
335 if (!client->netconnection)
338 MSG_WriteChar(&client->netconnection->message,svc_print);
339 MSG_WriteString(&client->netconnection->message, string);
347 single print to a specific client
349 centerprint(clientent, value)
352 static void VM_SV_centerprint (void)
356 char string[VM_STRINGTEMP_LENGTH];
358 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
360 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
362 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
364 VM_Warning("tried to centerprint to a non-client\n");
368 client = svs.clients + entnum-1;
369 if (!client->netconnection)
372 VM_VarString(1, string, sizeof(string));
373 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
374 MSG_WriteString(&client->netconnection->message, string);
381 particle(origin, color, count)
384 static void VM_SV_particle (void)
390 VM_SAFEPARMCOUNT(4, VM_SV_particle);
392 org = PRVM_G_VECTOR(OFS_PARM0);
393 dir = PRVM_G_VECTOR(OFS_PARM1);
394 color = PRVM_G_FLOAT(OFS_PARM2);
395 count = PRVM_G_FLOAT(OFS_PARM3);
396 SV_StartParticle (org, dir, (int)color, (int)count);
406 static void VM_SV_ambientsound (void)
410 float vol, attenuation;
413 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
415 pos = PRVM_G_VECTOR (OFS_PARM0);
416 samp = PRVM_G_STRING(OFS_PARM1);
417 vol = PRVM_G_FLOAT(OFS_PARM2);
418 attenuation = PRVM_G_FLOAT(OFS_PARM3);
420 // check to see if samp was properly precached
421 soundnum = SV_SoundIndex(samp, 1);
429 // add an svc_spawnambient command to the level signon packet
432 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
434 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
436 MSG_WriteVector(&sv.signon, pos, sv.protocol);
438 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
439 MSG_WriteShort (&sv.signon, soundnum);
441 MSG_WriteByte (&sv.signon, soundnum);
443 MSG_WriteByte (&sv.signon, (int)(vol*255));
444 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
452 Each entity can have eight independant sound sources, like voice,
455 Channel 0 is an auto-allocate channel, the others override anything
456 already running on that entity/channel pair.
458 An attenuation of 0 will play full volume everywhere in the level.
459 Larger attenuations will drop off.
463 static void VM_SV_sound (void)
467 prvm_edict_t *entity;
471 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
473 entity = PRVM_G_EDICT(OFS_PARM0);
474 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
475 sample = PRVM_G_STRING(OFS_PARM2);
476 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
477 attenuation = PRVM_G_FLOAT(OFS_PARM4);
480 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
484 if (volume < 0 || volume > 255)
486 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
490 if (attenuation < 0 || attenuation > 4)
492 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
496 if (channel < 0 || channel > 7)
498 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
502 SV_StartSound (entity, channel, sample, volume, attenuation);
509 Follows the same logic as VM_SV_sound, except instead of
510 an entity, an origin for the sound is provided, and channel
511 is omitted (since no entity is being tracked).
515 static void VM_SV_pointsound(void)
522 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
524 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
525 sample = PRVM_G_STRING(OFS_PARM1);
526 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
527 attenuation = PRVM_G_FLOAT(OFS_PARM3);
529 if (volume < 0 || volume > 255)
531 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
535 if (attenuation < 0 || attenuation > 4)
537 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
541 SV_StartPointSound (org, sample, volume, attenuation);
548 Used for use tracing and shot targeting
549 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
550 if the tryents flag is set.
552 traceline (vector1, vector2, movetype, ignore)
555 static void VM_SV_traceline (void)
562 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
564 prog->xfunction->builtinsprofile += 30;
566 v1 = PRVM_G_VECTOR(OFS_PARM0);
567 v2 = PRVM_G_VECTOR(OFS_PARM1);
568 move = (int)PRVM_G_FLOAT(OFS_PARM2);
569 ent = PRVM_G_EDICT(OFS_PARM3);
571 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]))
572 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));
574 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
576 VM_SetTraceGlobals(&trace);
584 Used for use tracing and shot targeting
585 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
586 if the tryents flag is set.
588 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
591 // LordHavoc: added this for my own use, VERY useful, similar to traceline
592 static void VM_SV_tracebox (void)
594 float *v1, *v2, *m1, *m2;
599 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
601 prog->xfunction->builtinsprofile += 30;
603 v1 = PRVM_G_VECTOR(OFS_PARM0);
604 m1 = PRVM_G_VECTOR(OFS_PARM1);
605 m2 = PRVM_G_VECTOR(OFS_PARM2);
606 v2 = PRVM_G_VECTOR(OFS_PARM3);
607 move = (int)PRVM_G_FLOAT(OFS_PARM4);
608 ent = PRVM_G_EDICT(OFS_PARM5);
610 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]))
611 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));
613 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
615 VM_SetTraceGlobals(&trace);
618 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
623 vec3_t original_origin;
624 vec3_t original_velocity;
625 vec3_t original_angles;
626 vec3_t original_avelocity;
630 VectorCopy(tossent->fields.server->origin , original_origin );
631 VectorCopy(tossent->fields.server->velocity , original_velocity );
632 VectorCopy(tossent->fields.server->angles , original_angles );
633 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
635 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
636 if (val != NULL && val->_float != 0)
637 gravity = val->_float;
640 gravity *= sv_gravity.value * 0.05;
642 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
644 SV_CheckVelocity (tossent);
645 tossent->fields.server->velocity[2] -= gravity;
646 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
647 VectorScale (tossent->fields.server->velocity, 0.05, move);
648 VectorAdd (tossent->fields.server->origin, move, end);
649 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
650 VectorCopy (trace.endpos, tossent->fields.server->origin);
652 if (trace.fraction < 1)
656 VectorCopy(original_origin , tossent->fields.server->origin );
657 VectorCopy(original_velocity , tossent->fields.server->velocity );
658 VectorCopy(original_angles , tossent->fields.server->angles );
659 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
664 static void VM_SV_tracetoss (void)
668 prvm_edict_t *ignore;
670 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
672 prog->xfunction->builtinsprofile += 600;
674 ent = PRVM_G_EDICT(OFS_PARM0);
675 if (ent == prog->edicts)
677 VM_Warning("tracetoss: can not use world entity\n");
680 ignore = PRVM_G_EDICT(OFS_PARM1);
682 trace = SV_Trace_Toss (ent, ignore);
684 VM_SetTraceGlobals(&trace);
687 //============================================================================
689 static int checkpvsbytes;
690 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
692 static int VM_SV_newcheckclient (int check)
698 // cycle to the next one
700 check = bound(1, check, svs.maxclients);
701 if (check == svs.maxclients)
709 prog->xfunction->builtinsprofile++;
711 if (i == svs.maxclients+1)
713 // look up the client's edict
714 ent = PRVM_EDICT_NUM(i);
715 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
716 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
718 // found a valid client (possibly the same one again)
722 // get the PVS for the entity
723 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
725 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
726 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
735 Returns a client (or object that has a client enemy) that would be a
738 If there is more than one valid option, they are cycled each frame
740 If (self.origin + self.viewofs) is not in the PVS of the current target,
741 it is not returned at all.
746 int c_invis, c_notvis;
747 static void VM_SV_checkclient (void)
749 prvm_edict_t *ent, *self;
752 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
754 // find a new check if on a new frame
755 if (sv.time - sv.lastchecktime >= 0.1)
757 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
758 sv.lastchecktime = sv.time;
761 // return check if it might be visible
762 ent = PRVM_EDICT_NUM(sv.lastcheck);
763 if (ent->priv.server->free || ent->fields.server->health <= 0)
765 VM_RETURN_EDICT(prog->edicts);
769 // if current entity can't possibly see the check entity, return 0
770 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
771 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
772 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
775 VM_RETURN_EDICT(prog->edicts);
779 // might be able to see it
781 VM_RETURN_EDICT(ent);
784 //============================================================================
791 Sends text over to the client's execution buffer
793 stuffcmd (clientent, value, ...)
796 static void VM_SV_stuffcmd (void)
800 char string[VM_STRINGTEMP_LENGTH];
802 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
804 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
805 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
807 VM_Warning("Can't stuffcmd to a non-client\n");
811 VM_VarString(1, string, sizeof(string));
814 host_client = svs.clients + entnum-1;
815 Host_ClientCommands ("%s", string);
823 Returns a chain of entities that have origins within a spherical area
825 findradius (origin, radius)
828 static void VM_SV_findradius (void)
830 prvm_edict_t *ent, *chain;
831 vec_t radius, radius2;
832 vec3_t org, eorg, mins, maxs;
835 prvm_edict_t *touchedicts[MAX_EDICTS];
837 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
839 chain = (prvm_edict_t *)prog->edicts;
841 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
842 radius = PRVM_G_FLOAT(OFS_PARM1);
843 radius2 = radius * radius;
845 mins[0] = org[0] - (radius + 1);
846 mins[1] = org[1] - (radius + 1);
847 mins[2] = org[2] - (radius + 1);
848 maxs[0] = org[0] + (radius + 1);
849 maxs[1] = org[1] + (radius + 1);
850 maxs[2] = org[2] + (radius + 1);
851 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
852 if (numtouchedicts > MAX_EDICTS)
854 // this never happens
855 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
856 numtouchedicts = MAX_EDICTS;
858 for (i = 0;i < numtouchedicts;i++)
860 ent = touchedicts[i];
861 prog->xfunction->builtinsprofile++;
862 // Quake did not return non-solid entities but darkplaces does
863 // (note: this is the reason you can't blow up fallen zombies)
864 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
866 // LordHavoc: compare against bounding box rather than center so it
867 // doesn't miss large objects, and use DotProduct instead of Length
868 // for a major speedup
869 VectorSubtract(org, ent->fields.server->origin, eorg);
870 if (sv_gameplayfix_findradiusdistancetobox.integer)
872 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
873 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
874 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
877 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
878 if (DotProduct(eorg, eorg) < radius2)
880 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
885 VM_RETURN_EDICT(chain);
888 static void VM_SV_precache_sound (void)
890 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
891 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
894 static void VM_SV_precache_model (void)
896 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
897 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
898 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
905 float(float yaw, float dist[, settrace]) walkmove
908 static void VM_SV_walkmove (void)
917 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
919 // assume failure if it returns early
920 PRVM_G_FLOAT(OFS_RETURN) = 0;
922 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
923 if (ent == prog->edicts)
925 VM_Warning("walkmove: can not modify world entity\n");
928 if (ent->priv.server->free)
930 VM_Warning("walkmove: can not modify free entity\n");
933 yaw = PRVM_G_FLOAT(OFS_PARM0);
934 dist = PRVM_G_FLOAT(OFS_PARM1);
935 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
937 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
940 yaw = yaw*M_PI*2 / 360;
942 move[0] = cos(yaw)*dist;
943 move[1] = sin(yaw)*dist;
946 // save program state, because SV_movestep may call other progs
947 oldf = prog->xfunction;
948 oldself = prog->globals.server->self;
950 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
953 // restore program state
954 prog->xfunction = oldf;
955 prog->globals.server->self = oldself;
965 static void VM_SV_droptofloor (void)
971 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
973 // assume failure if it returns early
974 PRVM_G_FLOAT(OFS_RETURN) = 0;
976 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
977 if (ent == prog->edicts)
979 VM_Warning("droptofloor: can not modify world entity\n");
982 if (ent->priv.server->free)
984 VM_Warning("droptofloor: can not modify free entity\n");
988 VectorCopy (ent->fields.server->origin, end);
991 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
992 SV_UnstickEntity(ent);
994 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
995 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
998 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]);
999 VectorAdd(ent->fields.server->origin, offset, org);
1000 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1001 VectorSubtract(trace.endpos, offset, trace.endpos);
1002 if (trace.startsolid)
1004 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]);
1005 SV_UnstickEntity(ent);
1006 SV_LinkEdict (ent, false);
1007 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1008 ent->fields.server->groundentity = 0;
1009 PRVM_G_FLOAT(OFS_RETURN) = 1;
1011 else if (trace.fraction < 1)
1013 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]);
1014 VectorCopy (trace.endpos, ent->fields.server->origin);
1015 SV_UnstickEntity(ent);
1016 SV_LinkEdict (ent, false);
1017 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1018 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1019 PRVM_G_FLOAT(OFS_RETURN) = 1;
1020 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1021 ent->priv.server->suspendedinairflag = true;
1026 if (trace.fraction != 1)
1028 if (trace.fraction < 1)
1029 VectorCopy (trace.endpos, ent->fields.server->origin);
1030 SV_LinkEdict (ent, false);
1031 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1032 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1033 PRVM_G_FLOAT(OFS_RETURN) = 1;
1034 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1035 ent->priv.server->suspendedinairflag = true;
1044 void(float style, string value) lightstyle
1047 static void VM_SV_lightstyle (void)
1054 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1056 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1057 val = PRVM_G_STRING(OFS_PARM1);
1059 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1060 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1063 // change the string in sv
1064 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1066 // send message to all clients on this server
1067 if (sv.state != ss_active)
1070 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1072 if (client->active && client->netconnection)
1074 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1075 MSG_WriteChar (&client->netconnection->message,style);
1076 MSG_WriteString (&client->netconnection->message, val);
1086 static void VM_SV_checkbottom (void)
1088 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1089 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1097 static void VM_SV_pointcontents (void)
1099 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1100 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1107 Pick a vector for the player to shoot along
1108 vector aim(entity, missilespeed)
1111 static void VM_SV_aim (void)
1113 prvm_edict_t *ent, *check, *bestent;
1114 vec3_t start, dir, end, bestdir;
1117 float dist, bestdist;
1120 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1122 // assume failure if it returns early
1123 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1124 // if sv_aim is so high it can't possibly accept anything, skip out early
1125 if (sv_aim.value >= 1)
1128 ent = PRVM_G_EDICT(OFS_PARM0);
1129 if (ent == prog->edicts)
1131 VM_Warning("aim: can not use world entity\n");
1134 if (ent->priv.server->free)
1136 VM_Warning("aim: can not use free entity\n");
1139 speed = PRVM_G_FLOAT(OFS_PARM1);
1141 VectorCopy (ent->fields.server->origin, start);
1144 // try sending a trace straight
1145 VectorCopy (prog->globals.server->v_forward, dir);
1146 VectorMA (start, 2048, dir, end);
1147 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1148 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1149 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1151 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1156 // try all possible entities
1157 VectorCopy (dir, bestdir);
1158 bestdist = sv_aim.value;
1161 check = PRVM_NEXT_EDICT(prog->edicts);
1162 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1164 prog->xfunction->builtinsprofile++;
1165 if (check->fields.server->takedamage != DAMAGE_AIM)
1169 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1170 continue; // don't aim at teammate
1171 for (j=0 ; j<3 ; j++)
1172 end[j] = check->fields.server->origin[j]
1173 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1174 VectorSubtract (end, start, dir);
1175 VectorNormalize (dir);
1176 dist = DotProduct (dir, prog->globals.server->v_forward);
1177 if (dist < bestdist)
1178 continue; // to far to turn
1179 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1180 if (tr.ent == check)
1181 { // can shoot at this one
1189 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1190 dist = DotProduct (dir, prog->globals.server->v_forward);
1191 VectorScale (prog->globals.server->v_forward, dist, end);
1193 VectorNormalize (end);
1194 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1198 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1203 ===============================================================================
1207 ===============================================================================
1210 #define MSG_BROADCAST 0 // unreliable to all
1211 #define MSG_ONE 1 // reliable to one (msg_entity)
1212 #define MSG_ALL 2 // reliable to all
1213 #define MSG_INIT 3 // write to the init string
1214 #define MSG_ENTITY 5
1216 sizebuf_t *WriteDest (void)
1222 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1226 return &sv.datagram;
1229 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1230 entnum = PRVM_NUM_FOR_EDICT(ent);
1231 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1233 VM_Warning ("WriteDest: tried to write to non-client\n");
1234 return &sv.reliable_datagram;
1237 return &svs.clients[entnum-1].netconnection->message;
1240 VM_Warning ("WriteDest: bad destination\n");
1242 return &sv.reliable_datagram;
1248 return sv.writeentitiestoclient_msg;
1254 static void VM_SV_WriteByte (void)
1256 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1257 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1260 static void VM_SV_WriteChar (void)
1262 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1263 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1266 static void VM_SV_WriteShort (void)
1268 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1269 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1272 static void VM_SV_WriteLong (void)
1274 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1275 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1278 static void VM_SV_WriteAngle (void)
1280 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1281 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1284 static void VM_SV_WriteCoord (void)
1286 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1287 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1290 static void VM_SV_WriteString (void)
1292 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1293 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1296 static void VM_SV_WriteUnterminatedString (void)
1298 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1299 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1303 static void VM_SV_WriteEntity (void)
1305 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1306 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1309 // writes a picture as at most size bytes of data
1311 // IMGNAME \0 SIZE(short) IMGDATA
1312 // if failed to read/compress:
1314 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1315 static void VM_SV_WritePicture (void)
1317 const char *imgname;
1321 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1323 imgname = PRVM_G_STRING(OFS_PARM1);
1324 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1328 MSG_WriteString(WriteDest(), imgname);
1329 if(Image_Compress(imgname, size, &buf, &size))
1332 MSG_WriteShort(WriteDest(), size);
1333 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1338 MSG_WriteShort(WriteDest(), 0);
1342 //////////////////////////////////////////////////////////
1344 static void VM_SV_makestatic (void)
1349 // allow 0 parameters due to an id1 qc bug in which this function is used
1350 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1351 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1353 if (prog->argc >= 1)
1354 ent = PRVM_G_EDICT(OFS_PARM0);
1356 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1357 if (ent == prog->edicts)
1359 VM_Warning("makestatic: can not modify world entity\n");
1362 if (ent->priv.server->free)
1364 VM_Warning("makestatic: can not modify free entity\n");
1369 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1374 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1375 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1376 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1378 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1380 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1381 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1382 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1386 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1387 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1388 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1391 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1392 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1393 for (i=0 ; i<3 ; i++)
1395 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1396 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1399 // throw the entity away now
1403 //=============================================================================
1410 static void VM_SV_setspawnparms (void)
1416 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1418 ent = PRVM_G_EDICT(OFS_PARM0);
1419 i = PRVM_NUM_FOR_EDICT(ent);
1420 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1422 Con_Print("tried to setspawnparms on a non-client\n");
1426 // copy spawn parms out of the client_t
1427 client = svs.clients + i-1;
1428 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1429 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1436 Returns a color vector indicating the lighting at the requested point.
1438 (Internal Operation note: actually measures the light beneath the point, just like
1439 the model lighting on the client)
1444 static void VM_SV_getlight (void)
1446 vec3_t ambientcolor, diffusecolor, diffusenormal;
1448 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1449 p = PRVM_G_VECTOR(OFS_PARM0);
1450 VectorClear(ambientcolor);
1451 VectorClear(diffusecolor);
1452 VectorClear(diffusenormal);
1453 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1454 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1455 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1460 unsigned char type; // 1/2/8 or other value if isn't used
1464 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1465 static int vm_customstats_last;
1467 void VM_CustomStats_Clear (void)
1471 Z_Free(vm_customstats);
1472 vm_customstats = NULL;
1473 vm_customstats_last = -1;
1477 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1485 for(i=0; i<vm_customstats_last+1 ;i++)
1487 if(!vm_customstats[i].type)
1489 switch(vm_customstats[i].type)
1491 //string as 16 bytes
1494 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1495 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1496 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1497 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1498 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1500 //float field sent as-is
1502 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1504 //integer value of float field
1506 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1514 // void(float index, float type, .void field) SV_AddStat = #232;
1515 // Set up an auto-sent player stat.
1516 // Client's get thier own fields sent to them. Index may not be less than 32.
1517 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1518 // 1: string (4 stats carrying a total of 16 charactures)
1519 // 2: float (one stat, float converted to an integer for transportation)
1520 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1521 static void VM_SV_AddStat (void)
1526 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1530 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1533 VM_Warning("PF_SV_AddStat: not enough memory\n");
1537 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1538 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1539 off = PRVM_G_INT (OFS_PARM2);
1544 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1547 if(i >= (MAX_CL_STATS-32))
1549 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1552 if(i > (MAX_CL_STATS-32-4) && type == 1)
1554 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1557 vm_customstats[i].type = type;
1558 vm_customstats[i].fieldoffset = off;
1559 if(vm_customstats_last < i)
1560 vm_customstats_last = i;
1567 copies data from one entity to another
1569 copyentity(src, dst)
1572 static void VM_SV_copyentity (void)
1574 prvm_edict_t *in, *out;
1575 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1576 in = PRVM_G_EDICT(OFS_PARM0);
1577 if (in == prog->edicts)
1579 VM_Warning("copyentity: can not read world entity\n");
1582 if (in->priv.server->free)
1584 VM_Warning("copyentity: can not read free entity\n");
1587 out = PRVM_G_EDICT(OFS_PARM1);
1588 if (out == prog->edicts)
1590 VM_Warning("copyentity: can not modify world entity\n");
1593 if (out->priv.server->free)
1595 VM_Warning("copyentity: can not modify free entity\n");
1598 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1599 SV_LinkEdict(out, false);
1607 sets the color of a client and broadcasts the update to all connected clients
1609 setcolor(clientent, value)
1612 static void VM_SV_setcolor (void)
1618 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1619 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1620 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1622 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1624 Con_Print("tried to setcolor a non-client\n");
1628 client = svs.clients + entnum-1;
1631 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1633 client->edict->fields.server->team = (i & 15) + 1;
1636 if (client->old_colors != client->colors)
1638 client->old_colors = client->colors;
1639 // send notification to all clients
1640 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1641 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1642 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1650 effect(origin, modelname, startframe, framecount, framerate)
1653 static void VM_SV_effect (void)
1657 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1658 s = PRVM_G_STRING(OFS_PARM1);
1661 VM_Warning("effect: no model specified\n");
1665 i = SV_ModelIndex(s, 1);
1668 VM_Warning("effect: model not precached\n");
1672 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1674 VM_Warning("effect: framecount < 1\n");
1678 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1680 VM_Warning("effect: framerate < 1\n");
1684 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));
1687 static void VM_SV_te_blood (void)
1689 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1690 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1692 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1693 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1696 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1697 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1699 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1700 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1701 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1703 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1704 SV_FlushBroadcastMessages();
1707 static void VM_SV_te_bloodshower (void)
1709 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1710 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1712 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1713 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1725 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1726 SV_FlushBroadcastMessages();
1729 static void VM_SV_te_explosionrgb (void)
1731 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1732 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1733 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1735 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1736 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1739 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1740 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1741 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1742 SV_FlushBroadcastMessages();
1745 static void VM_SV_te_particlecube (void)
1747 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1748 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1750 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1751 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1753 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1754 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1763 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1765 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1767 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1768 // gravity true/false
1769 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1771 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1772 SV_FlushBroadcastMessages();
1775 static void VM_SV_te_particlerain (void)
1777 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1778 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1780 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1781 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1783 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1784 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1785 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1792 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1793 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1795 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1797 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1798 SV_FlushBroadcastMessages();
1801 static void VM_SV_te_particlesnow (void)
1803 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1804 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1806 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1807 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1821 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1823 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1824 SV_FlushBroadcastMessages();
1827 static void VM_SV_te_spark (void)
1829 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1830 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1832 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1833 MSG_WriteByte(&sv.datagram, TE_SPARK);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1839 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1840 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1841 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1843 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1844 SV_FlushBroadcastMessages();
1847 static void VM_SV_te_gunshotquad (void)
1849 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1850 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1851 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1856 SV_FlushBroadcastMessages();
1859 static void VM_SV_te_spikequad (void)
1861 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1862 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1863 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1868 SV_FlushBroadcastMessages();
1871 static void VM_SV_te_superspikequad (void)
1873 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1874 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1875 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1880 SV_FlushBroadcastMessages();
1883 static void VM_SV_te_explosionquad (void)
1885 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1886 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1887 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1892 SV_FlushBroadcastMessages();
1895 static void VM_SV_te_smallflash (void)
1897 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1898 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1899 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1904 SV_FlushBroadcastMessages();
1907 static void VM_SV_te_customflash (void)
1909 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1910 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1912 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1913 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1915 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1916 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1917 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1919 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1921 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1923 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1924 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1925 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1926 SV_FlushBroadcastMessages();
1929 static void VM_SV_te_gunshot (void)
1931 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1932 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1933 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1938 SV_FlushBroadcastMessages();
1941 static void VM_SV_te_spike (void)
1943 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1944 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1945 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1947 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1948 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1950 SV_FlushBroadcastMessages();
1953 static void VM_SV_te_superspike (void)
1955 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1956 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1957 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1962 SV_FlushBroadcastMessages();
1965 static void VM_SV_te_explosion (void)
1967 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1968 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1969 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1974 SV_FlushBroadcastMessages();
1977 static void VM_SV_te_tarexplosion (void)
1979 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1980 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1981 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1986 SV_FlushBroadcastMessages();
1989 static void VM_SV_te_wizspike (void)
1991 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1992 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1993 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1998 SV_FlushBroadcastMessages();
2001 static void VM_SV_te_knightspike (void)
2003 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2004 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2005 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2010 SV_FlushBroadcastMessages();
2013 static void VM_SV_te_lavasplash (void)
2015 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2016 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2017 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2020 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2021 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2022 SV_FlushBroadcastMessages();
2025 static void VM_SV_te_teleport (void)
2027 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2028 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2029 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2033 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2034 SV_FlushBroadcastMessages();
2037 static void VM_SV_te_explosion2 (void)
2039 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2040 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2041 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2043 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2044 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2045 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2047 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2048 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2049 SV_FlushBroadcastMessages();
2052 static void VM_SV_te_lightning1 (void)
2054 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2055 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2056 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2058 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2060 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2061 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2065 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2067 SV_FlushBroadcastMessages();
2070 static void VM_SV_te_lightning2 (void)
2072 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2073 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2074 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2076 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2078 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2079 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2080 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2082 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2083 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2084 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2085 SV_FlushBroadcastMessages();
2088 static void VM_SV_te_lightning3 (void)
2090 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2091 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2092 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2094 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2096 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2101 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2102 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2103 SV_FlushBroadcastMessages();
2106 static void VM_SV_te_beam (void)
2108 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2109 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2110 MSG_WriteByte(&sv.datagram, TE_BEAM);
2112 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2114 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2115 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2116 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2118 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2119 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2120 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2121 SV_FlushBroadcastMessages();
2124 static void VM_SV_te_plasmaburn (void)
2126 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2127 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2128 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2129 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2130 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2131 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2132 SV_FlushBroadcastMessages();
2135 static void VM_SV_te_flamejet (void)
2137 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2138 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2139 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2141 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2142 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2143 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2145 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2146 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2147 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2149 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2150 SV_FlushBroadcastMessages();
2153 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2156 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2158 bestdist = 1000000000;
2160 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2162 // clip original point to each triangle of the surface and find the
2163 // triangle that is closest
2164 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2165 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2166 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2167 TriangleNormal(v[0], v[1], v[2], facenormal);
2168 VectorNormalize(facenormal);
2169 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2170 VectorMA(p, offsetdist, facenormal, temp);
2171 for (j = 0, k = 2;j < 3;k = j, j++)
2173 VectorSubtract(v[k], v[j], edgenormal);
2174 CrossProduct(edgenormal, facenormal, sidenormal);
2175 VectorNormalize(sidenormal);
2176 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2178 VectorMA(temp, offsetdist, sidenormal, temp);
2180 dist = VectorDistance2(temp, p);
2181 if (bestdist > dist)
2184 VectorCopy(temp, out);
2189 static dp_model_t *getmodel(prvm_edict_t *ed)
2192 if (!ed || ed->priv.server->free)
2194 modelindex = (int)ed->fields.server->modelindex;
2195 if (modelindex < 1 || modelindex >= MAX_MODELS)
2197 return sv.models[modelindex];
2200 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2202 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2204 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2208 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2209 static void VM_SV_getsurfacenumpoints(void)
2212 msurface_t *surface;
2213 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2214 // return 0 if no such surface
2215 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2217 PRVM_G_FLOAT(OFS_RETURN) = 0;
2221 // note: this (incorrectly) assumes it is a simple polygon
2222 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2224 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2225 static void VM_SV_getsurfacepoint(void)
2229 msurface_t *surface;
2231 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2232 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2233 ed = PRVM_G_EDICT(OFS_PARM0);
2234 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2236 // note: this (incorrectly) assumes it is a simple polygon
2237 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2238 if (pointnum < 0 || pointnum >= surface->num_vertices)
2240 // FIXME: implement rotation/scaling
2241 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2243 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2244 // float SPA_POSITION = 0;
2245 // float SPA_S_AXIS = 1;
2246 // float SPA_T_AXIS = 2;
2247 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2248 // float SPA_TEXCOORDS0 = 4;
2249 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2250 // float SPA_LIGHTMAP0_COLOR = 6;
2251 static void VM_SV_getsurfacepointattribute(void)
2255 msurface_t *surface;
2259 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2260 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2261 ed = PRVM_G_EDICT(OFS_PARM0);
2262 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2264 // note: this (incorrectly) assumes it is a simple polygon
2265 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2266 if (pointnum < 0 || pointnum >= surface->num_vertices)
2268 // FIXME: implement rotation/scaling
2269 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2271 switch( attributetype ) {
2272 // float SPA_POSITION = 0;
2274 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2276 // float SPA_S_AXIS = 1;
2278 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2280 // float SPA_T_AXIS = 2;
2282 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2284 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2286 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2288 // float SPA_TEXCOORDS0 = 4;
2290 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2291 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2292 ret[0] = texcoord[0];
2293 ret[1] = texcoord[1];
2297 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2299 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2300 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2301 ret[0] = texcoord[0];
2302 ret[1] = texcoord[1];
2306 // float SPA_LIGHTMAP0_COLOR = 6;
2308 // ignore alpha for now..
2309 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2312 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2316 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2317 static void VM_SV_getsurfacenormal(void)
2320 msurface_t *surface;
2322 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2323 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2324 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2326 // FIXME: implement rotation/scaling
2327 // note: this (incorrectly) assumes it is a simple polygon
2328 // note: this only returns the first triangle, so it doesn't work very
2329 // well for curved surfaces or arbitrary meshes
2330 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);
2331 VectorNormalize(normal);
2332 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2334 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2335 static void VM_SV_getsurfacetexture(void)
2338 msurface_t *surface;
2339 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2340 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2341 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2343 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2345 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2346 static void VM_SV_getsurfacenearpoint(void)
2348 int surfacenum, best;
2350 vec_t dist, bestdist;
2353 msurface_t *surface;
2355 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2356 PRVM_G_FLOAT(OFS_RETURN) = -1;
2357 ed = PRVM_G_EDICT(OFS_PARM0);
2358 point = PRVM_G_VECTOR(OFS_PARM1);
2360 if (!ed || ed->priv.server->free)
2362 model = getmodel(ed);
2363 if (!model || !model->num_surfaces)
2366 // FIXME: implement rotation/scaling
2367 VectorSubtract(point, ed->fields.server->origin, p);
2369 bestdist = 1000000000;
2370 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2372 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2373 // first see if the nearest point on the surface's box is closer than the previous match
2374 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2375 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2376 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2377 dist = VectorLength2(clipped);
2378 if (dist < bestdist)
2380 // it is, check the nearest point on the actual geometry
2381 clippointtosurface(model, surface, p, clipped);
2382 VectorSubtract(clipped, p, clipped);
2383 dist += VectorLength2(clipped);
2384 if (dist < bestdist)
2386 // that's closer too, store it as the best match
2392 PRVM_G_FLOAT(OFS_RETURN) = best;
2394 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2395 static void VM_SV_getsurfaceclippedpoint(void)
2399 msurface_t *surface;
2401 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2402 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2403 ed = PRVM_G_EDICT(OFS_PARM0);
2404 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2406 // FIXME: implement rotation/scaling
2407 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2408 clippointtosurface(model, surface, p, out);
2409 // FIXME: implement rotation/scaling
2410 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2413 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2414 //this function originally written by KrimZon, made shorter by LordHavoc
2415 static void VM_SV_clientcommand (void)
2417 client_t *temp_client;
2419 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2421 //find client for this entity
2422 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2423 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2425 Con_Print("PF_clientcommand: entity is not a client\n");
2429 temp_client = host_client;
2430 host_client = svs.clients + i;
2431 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2432 host_client = temp_client;
2435 //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)
2436 static void VM_SV_setattachment (void)
2438 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2439 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2440 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2444 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2446 if (e == prog->edicts)
2448 VM_Warning("setattachment: can not modify world entity\n");
2451 if (e->priv.server->free)
2453 VM_Warning("setattachment: can not modify free entity\n");
2457 if (tagentity == NULL)
2458 tagentity = prog->edicts;
2460 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2462 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2464 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2467 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2469 modelindex = (int)tagentity->fields.server->modelindex;
2470 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2472 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2474 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);
2477 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));
2481 /////////////////////////////////////////
2482 // DP_MD3_TAGINFO extension coded by VorteX
2484 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2489 i = (int)e->fields.server->modelindex;
2490 if (i < 1 || i >= MAX_MODELS)
2492 model = sv.models[i];
2494 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2497 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2499 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2503 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);
2505 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);
2508 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2514 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2515 && (model = sv.models[(int)ent->fields.server->modelindex])
2516 && model->animscenes)
2518 // if model has wrong frame, engine automatically switches to model first frame
2519 frame = (int)ent->fields.server->frame;
2520 if (frame < 0 || frame >= model->numframes)
2522 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2524 *out = identitymatrix;
2528 // Warnings/errors code:
2529 // 0 - normal (everything all-right)
2532 // 3 - null or non-precached model
2533 // 4 - no tags with requested index
2534 // 5 - runaway loop at attachment chain
2535 extern cvar_t cl_bob;
2536 extern cvar_t cl_bobcycle;
2537 extern cvar_t cl_bobup;
2538 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2542 int modelindex, attachloop;
2543 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2546 *out = identitymatrix; // warnings and errors return identical matrix
2548 if (ent == prog->edicts)
2550 if (ent->priv.server->free)
2553 modelindex = (int)ent->fields.server->modelindex;
2554 if (modelindex <= 0 || modelindex > MAX_MODELS)
2557 model = sv.models[modelindex];
2559 tagmatrix = identitymatrix;
2560 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2564 if (attachloop >= 256) // prevent runaway looping
2566 // apply transformation by child's tagindex on parent entity and then
2567 // by parent entity itself
2568 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2569 if (ret && attachloop == 0)
2571 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2572 SV_GetEntityMatrix(ent, &entitymatrix, false);
2573 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2574 // next iteration we process the parent entity
2575 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2577 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2578 ent = PRVM_EDICT_NUM(val->edict);
2585 // RENDER_VIEWMODEL magic
2586 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2588 Matrix4x4_Copy(&tagmatrix, out);
2589 ent = PRVM_EDICT_NUM(val->edict);
2591 SV_GetEntityMatrix(ent, &entitymatrix, true);
2592 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2595 // Cl_bob, ported from rendering code
2596 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2599 // LordHavoc: this code is *weird*, but not replacable (I think it
2600 // should be done in QC on the server, but oh well, quake is quake)
2601 // LordHavoc: figured out bobup: the time at which the sin is at 180
2602 // degrees (which allows lengthening or squishing the peak or valley)
2603 cycle = sv.time/cl_bobcycle.value;
2604 cycle -= (int)cycle;
2605 if (cycle < cl_bobup.value)
2606 cycle = sin(M_PI * cycle / cl_bobup.value);
2608 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2609 // bob is proportional to velocity in the xy plane
2610 // (don't count Z, or jumping messes it up)
2611 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;
2612 bob = bob*0.3 + bob*0.7*cycle;
2613 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2620 //float(entity ent, string tagname) gettagindex;
2622 static void VM_SV_gettagindex (void)
2625 const char *tag_name;
2626 int modelindex, tag_index;
2628 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2630 ent = PRVM_G_EDICT(OFS_PARM0);
2631 tag_name = PRVM_G_STRING(OFS_PARM1);
2633 if (ent == prog->edicts)
2635 VM_Warning("gettagindex: can't affect world entity\n");
2638 if (ent->priv.server->free)
2640 VM_Warning("gettagindex: can't affect free entity\n");
2644 modelindex = (int)ent->fields.server->modelindex;
2646 if (modelindex <= 0 || modelindex > MAX_MODELS)
2647 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2650 tag_index = SV_GetTagIndex(ent, tag_name);
2652 if(developer.integer >= 100)
2653 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2655 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2658 //vector(entity ent, float tagindex) gettaginfo;
2659 static void VM_SV_gettaginfo (void)
2663 matrix4x4_t tag_matrix;
2666 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2668 e = PRVM_G_EDICT(OFS_PARM0);
2669 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2671 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2672 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2677 VM_Warning("gettagindex: can't affect world entity\n");
2680 VM_Warning("gettagindex: can't affect free entity\n");
2683 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2686 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2689 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2694 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2695 static void VM_SV_dropclient (void)
2698 client_t *oldhostclient;
2699 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2700 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2701 if (clientnum < 0 || clientnum >= svs.maxclients)
2703 VM_Warning("dropclient: not a client\n");
2706 if (!svs.clients[clientnum].active)
2708 VM_Warning("dropclient: that client slot is not connected\n");
2711 oldhostclient = host_client;
2712 host_client = svs.clients + clientnum;
2713 SV_DropClient(false);
2714 host_client = oldhostclient;
2717 //entity() spawnclient (DP_SV_BOTCLIENT)
2718 static void VM_SV_spawnclient (void)
2722 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2723 prog->xfunction->builtinsprofile += 2;
2725 for (i = 0;i < svs.maxclients;i++)
2727 if (!svs.clients[i].active)
2729 prog->xfunction->builtinsprofile += 100;
2730 SV_ConnectClient (i, NULL);
2731 // this has to be set or else ClientDisconnect won't be called
2732 // we assume the qc will call ClientConnect...
2733 svs.clients[i].clientconnectcalled = true;
2734 ed = PRVM_EDICT_NUM(i + 1);
2738 VM_RETURN_EDICT(ed);
2741 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2742 static void VM_SV_clienttype (void)
2745 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2746 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2747 if (clientnum < 0 || clientnum >= svs.maxclients)
2748 PRVM_G_FLOAT(OFS_RETURN) = 3;
2749 else if (!svs.clients[clientnum].active)
2750 PRVM_G_FLOAT(OFS_RETURN) = 0;
2751 else if (svs.clients[clientnum].netconnection)
2752 PRVM_G_FLOAT(OFS_RETURN) = 1;
2754 PRVM_G_FLOAT(OFS_RETURN) = 2;
2761 string(string key) serverkey
2764 void VM_SV_serverkey(void)
2766 char string[VM_STRINGTEMP_LENGTH];
2767 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2768 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2769 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2772 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2773 static void VM_SV_setmodelindex (void)
2778 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2780 e = PRVM_G_EDICT(OFS_PARM0);
2781 if (e == prog->edicts)
2783 VM_Warning("setmodelindex: can not modify world entity\n");
2786 if (e->priv.server->free)
2788 VM_Warning("setmodelindex: can not modify free entity\n");
2791 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2792 if (i <= 0 || i > MAX_MODELS)
2794 VM_Warning("setmodelindex: invalid modelindex\n");
2797 if (!sv.model_precache[i][0])
2799 VM_Warning("setmodelindex: model not precached\n");
2803 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2804 e->fields.server->modelindex = i;
2810 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2811 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2813 SetMinMaxSize (e, quakemins, quakemaxs, true);
2816 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2819 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2820 static void VM_SV_modelnameforindex (void)
2823 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2825 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2827 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2828 if (i <= 0 || i > MAX_MODELS)
2830 VM_Warning("modelnameforindex: invalid modelindex\n");
2833 if (!sv.model_precache[i][0])
2835 VM_Warning("modelnameforindex: model not precached\n");
2839 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2842 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2843 static void VM_SV_particleeffectnum (void)
2846 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2847 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2850 PRVM_G_FLOAT(OFS_RETURN) = i;
2853 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2854 static void VM_SV_trailparticles (void)
2856 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2858 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2861 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2862 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2863 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2864 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2865 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2866 SV_FlushBroadcastMessages();
2869 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2870 static void VM_SV_pointparticles (void)
2872 int effectnum, count;
2874 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2876 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2879 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2880 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2881 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2882 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2883 if (count == 1 && !VectorLength2(vel))
2886 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2887 MSG_WriteShort(&sv.datagram, effectnum);
2888 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2892 // 1+2+12+12+2=29 bytes
2893 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2894 MSG_WriteShort(&sv.datagram, effectnum);
2895 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2896 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2897 MSG_WriteShort(&sv.datagram, count);
2900 SV_FlushBroadcastMessages();
2903 prvm_builtin_t vm_sv_builtins[] = {
2904 NULL, // #0 NULL function (not callable) (QUAKE)
2905 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2906 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2907 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2908 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2909 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2910 VM_break, // #6 void() break (QUAKE)
2911 VM_random, // #7 float() random (QUAKE)
2912 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2913 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2914 VM_error, // #10 void(string e) error (QUAKE)
2915 VM_objerror, // #11 void(string e) objerror (QUAKE)
2916 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2917 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2918 VM_spawn, // #14 entity() spawn (QUAKE)
2919 VM_remove, // #15 void(entity e) remove (QUAKE)
2920 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2921 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2922 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2923 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2924 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2925 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2926 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2927 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2928 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2929 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2930 VM_ftos, // #26 string(float f) ftos (QUAKE)
2931 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2932 VM_coredump, // #28 void() coredump (QUAKE)
2933 VM_traceon, // #29 void() traceon (QUAKE)
2934 VM_traceoff, // #30 void() traceoff (QUAKE)
2935 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2936 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2937 NULL, // #33 (QUAKE)
2938 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2939 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2940 VM_rint, // #36 float(float v) rint (QUAKE)
2941 VM_floor, // #37 float(float v) floor (QUAKE)
2942 VM_ceil, // #38 float(float v) ceil (QUAKE)
2943 NULL, // #39 (QUAKE)
2944 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2945 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2946 NULL, // #42 (QUAKE)
2947 VM_fabs, // #43 float(float f) fabs (QUAKE)
2948 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2949 VM_cvar, // #45 float(string s) cvar (QUAKE)
2950 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2951 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2952 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2953 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2954 NULL, // #50 (QUAKE)
2955 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2956 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2957 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2958 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2959 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2960 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2961 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2962 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2963 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2964 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2965 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2966 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2967 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2968 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2969 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2970 NULL, // #66 (QUAKE)
2971 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2972 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2973 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2974 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2975 NULL, // #71 (QUAKE)
2976 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2977 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2978 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2979 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2980 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2981 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2982 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2983 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2984 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2985 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2986 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2987 NULL, // #83 (QUAKE)
2988 NULL, // #84 (QUAKE)
2989 NULL, // #85 (QUAKE)
2990 NULL, // #86 (QUAKE)
2991 NULL, // #87 (QUAKE)
2992 NULL, // #88 (QUAKE)
2993 NULL, // #89 (QUAKE)
2994 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2995 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2996 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2997 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2998 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2999 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3000 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3001 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3002 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3003 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3004 // FrikaC and Telejano range #100-#199
3015 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3016 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3017 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3018 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3019 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3020 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3021 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3022 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3023 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3024 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3105 // FTEQW range #200-#299
3124 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3127 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3128 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3129 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3130 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3131 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3132 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3133 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3134 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3135 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3136 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3138 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3206 // CSQC range #300-#399
3207 NULL, // #300 void() clearscene (EXT_CSQC)
3208 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3209 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3210 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3211 NULL, // #304 void() renderscene (EXT_CSQC)
3212 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3213 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3214 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3215 NULL, // #308 void() R_EndPolygon
3217 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3218 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3222 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3223 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3224 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3225 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3226 NULL, // #319 void(string name) freepic (EXT_CSQC)
3227 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3228 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3229 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3230 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3231 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3232 NULL, // #325 void(void) drawresetcliparea
3237 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3238 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3239 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3240 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3241 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3242 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3243 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3244 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3245 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3246 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3247 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3248 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3249 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3250 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3251 NULL, // #344 vector() getmousepos (EXT_CSQC)
3252 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3253 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3254 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3255 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3256 NULL, // #349 float() isdemo (EXT_CSQC)
3257 VM_isserver, // #350 float() isserver (EXT_CSQC)
3258 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3259 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3260 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3261 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3267 NULL, // #360 float() readbyte (EXT_CSQC)
3268 NULL, // #361 float() readchar (EXT_CSQC)
3269 NULL, // #362 float() readshort (EXT_CSQC)
3270 NULL, // #363 float() readlong (EXT_CSQC)
3271 NULL, // #364 float() readcoord (EXT_CSQC)
3272 NULL, // #365 float() readangle (EXT_CSQC)
3273 NULL, // #366 string() readstring (EXT_CSQC)
3274 NULL, // #367 float() readfloat (EXT_CSQC)
3307 // LordHavoc's range #400-#499
3308 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3309 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3310 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3311 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3312 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3313 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3314 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3315 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3316 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)
3317 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3318 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3319 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3320 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3321 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3322 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3323 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3324 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3325 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3326 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3327 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3328 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3329 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3330 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3331 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3332 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3333 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3334 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3335 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3336 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3337 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3338 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3339 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3340 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3341 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3342 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3343 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3344 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3345 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3346 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3347 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3348 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3349 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3350 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3351 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3352 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3353 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3354 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3355 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3356 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3357 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3358 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3359 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3360 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3361 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3362 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3363 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3364 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3365 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3367 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3368 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3369 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3370 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3371 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3372 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3373 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3374 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3375 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3376 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3377 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3379 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3380 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3381 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3382 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3383 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3384 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3385 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3386 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3387 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3388 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3389 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3390 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3391 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3392 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3393 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3394 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3402 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3403 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3404 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3405 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3406 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3407 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3408 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3409 VM_SV_WritePicture, // #501
3411 VM_whichpack, // #503 string(string) whichpack = #503;
3418 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3419 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3420 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3421 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3422 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3423 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3424 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3425 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3426 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3430 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3432 void VM_SV_Cmd_Init(void)
3437 void VM_SV_Cmd_Reset(void)
3439 if(prog->funcoffsets.SV_Shutdown)
3441 func_t s = prog->funcoffsets.SV_Shutdown;
3442 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3443 PRVM_ExecuteProgram(s,"SV_Shutdown() required");