3 //============================================================================
6 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2", "maximum cosine angle for quake's vertical autoaim, a value above 1 completely disables the autoaim, quake used 0.93"}; //"0.93"}; // LordHavoc: disabled autoaim by default
9 char *vm_sv_extensions =
11 "DP_CON_ALIASPARAMETERS "
30 "DP_ENT_CUSTOMCOLORMAP "
31 "DP_ENT_EXTERIORMODELTOCLIENT "
33 "DP_ENT_LOWPRECISION "
36 "DP_GFX_EXTERNALTEXTURES "
37 "DP_GFX_EXTERNALTEXTURES_PERMAP "
39 "DP_GFX_QUAKE3MODELTAGS "
43 "DP_HALFLIFE_MAP_CVAR "
49 "DP_MOVETYPEBOUNCEMISSILE "
56 "DP_QC_FINDCHAINFLAGS "
57 "DP_QC_FINDCHAINFLOAT "
60 "DP_QC_FS_SEARCH " // Black: same as in the menu qc
65 "DP_QC_MULTIPLETEMPSTRINGS "
67 "DP_QC_SINCOSSQRTPOW "
68 "DP_QC_STRINGBUFFERS "
71 "DP_QC_TRACE_MOVETYPE_HITMODEL "
72 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
73 "DP_QC_VECTORVECTORS "
79 "DP_SND_DIRECTIONLESSATTNNONE "
88 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
89 "DP_SV_DRAWONLYTOCLIENT "
92 "DP_SV_NODRAWTOCLIENT "
94 "DP_SV_PLAYERPHYSICS "
95 "DP_SV_PRECACHEANYTIME "
97 "DP_SV_ROTATINGBMODEL "
100 "DP_SV_WRITEUNTERMINATEDSTRING "
104 "DP_TE_EXPLOSIONRGB "
106 "DP_TE_PARTICLECUBE "
107 "DP_TE_PARTICLERAIN "
108 "DP_TE_PARTICLESNOW "
110 "DP_TE_QUADEFFECTS1 "
113 "DP_TE_STANDARDEFFECTBUILTINS "
114 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
117 //"EXT_CSQC " // not ready yet
119 "KRIMZON_SV_PARSECLIENTCOMMAND "
123 "PRYDON_CLIENTCURSOR "
124 "TENEBRAE_GFX_DLIGHTS "
126 "NEXUIZ_PLAYERMODEL "
133 Writes new values for v_forward, v_up, and v_right based on angles
137 void PF_makevectors (void)
139 AngleVectors (PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
146 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.
148 setorigin (entity, origin)
151 void PF_setorigin (void)
156 e = PRVM_G_EDICT(OFS_PARM0);
157 if (e == prog->edicts)
159 VM_Warning("setorigin: can not modify world entity\n");
162 if (e->priv.server->free)
164 VM_Warning("setorigin: can not modify free entity\n");
167 org = PRVM_G_VECTOR(OFS_PARM1);
168 VectorCopy (org, e->fields.server->origin);
169 SV_LinkEdict (e, false);
173 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
177 for (i=0 ; i<3 ; i++)
179 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
181 // set derived values
182 VectorCopy (min, e->fields.server->mins);
183 VectorCopy (max, e->fields.server->maxs);
184 VectorSubtract (max, min, e->fields.server->size);
186 SV_LinkEdict (e, false);
193 the size box is rotated by the current angle
194 LordHavoc: no it isn't...
196 setsize (entity, minvector, maxvector)
199 void PF_setsize (void)
204 e = PRVM_G_EDICT(OFS_PARM0);
205 if (e == prog->edicts)
207 VM_Warning("setsize: can not modify world entity\n");
210 if (e->priv.server->free)
212 VM_Warning("setsize: can not modify free entity\n");
215 min = PRVM_G_VECTOR(OFS_PARM1);
216 max = PRVM_G_VECTOR(OFS_PARM2);
217 SetMinMaxSize (e, min, max, false);
225 setmodel(entity, model)
228 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
229 void PF_setmodel (void)
235 e = PRVM_G_EDICT(OFS_PARM0);
236 if (e == prog->edicts)
238 VM_Warning("setmodel: can not modify world entity\n");
241 if (e->priv.server->free)
243 VM_Warning("setmodel: can not modify free entity\n");
246 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
247 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
248 e->fields.server->modelindex = i;
254 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
255 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
257 SetMinMaxSize (e, quakemins, quakemaxs, true);
260 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
267 single print to a specific client
269 sprint(clientent, value)
272 void PF_sprint (void)
276 char string[VM_STRINGTEMP_LENGTH];
278 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
280 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
282 VM_Warning("tried to centerprint to a non-client\n");
286 client = svs.clients + entnum-1;
287 if (!client->netconnection)
290 VM_VarString(1, string, sizeof(string));
291 MSG_WriteChar(&client->netconnection->message,svc_print);
292 MSG_WriteString(&client->netconnection->message, string);
300 single print to a specific client
302 centerprint(clientent, value)
305 void PF_centerprint (void)
309 char string[VM_STRINGTEMP_LENGTH];
311 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
313 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
315 VM_Warning("tried to centerprint to a non-client\n");
319 client = svs.clients + entnum-1;
320 if (!client->netconnection)
323 VM_VarString(1, string, sizeof(string));
324 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
325 MSG_WriteString(&client->netconnection->message, string);
332 particle(origin, color, count)
335 void PF_particle (void)
341 org = PRVM_G_VECTOR(OFS_PARM0);
342 dir = PRVM_G_VECTOR(OFS_PARM1);
343 color = PRVM_G_FLOAT(OFS_PARM2);
344 count = PRVM_G_FLOAT(OFS_PARM3);
345 SV_StartParticle (org, dir, (int)color, (int)count);
355 void PF_ambientsound (void)
359 float vol, attenuation;
362 pos = PRVM_G_VECTOR (OFS_PARM0);
363 samp = PRVM_G_STRING(OFS_PARM1);
364 vol = PRVM_G_FLOAT(OFS_PARM2);
365 attenuation = PRVM_G_FLOAT(OFS_PARM3);
367 // check to see if samp was properly precached
368 soundnum = SV_SoundIndex(samp, 1);
376 // add an svc_spawnambient command to the level signon packet
379 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
381 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
383 MSG_WriteVector(&sv.signon, pos, sv.protocol);
386 MSG_WriteShort (&sv.signon, soundnum);
388 MSG_WriteByte (&sv.signon, soundnum);
390 MSG_WriteByte (&sv.signon, (int)(vol*255));
391 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
399 Each entity can have eight independant sound sources, like voice,
402 Channel 0 is an auto-allocate channel, the others override anything
403 already running on that entity/channel pair.
405 An attenuation of 0 will play full volume everywhere in the level.
406 Larger attenuations will drop off.
414 prvm_edict_t *entity;
418 entity = PRVM_G_EDICT(OFS_PARM0);
419 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
420 sample = PRVM_G_STRING(OFS_PARM2);
421 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
422 attenuation = PRVM_G_FLOAT(OFS_PARM4);
424 if (volume < 0 || volume > 255)
426 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
430 if (attenuation < 0 || attenuation > 4)
432 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
436 if (channel < 0 || channel > 7)
438 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
442 SV_StartSound (entity, channel, sample, volume, attenuation);
449 Used for use tracing and shot targeting
450 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
451 if the tryents flag is set.
453 traceline (vector1, vector2, tryents)
456 void PF_traceline (void)
464 prog->xfunction->builtinsprofile += 30;
466 v1 = PRVM_G_VECTOR(OFS_PARM0);
467 v2 = PRVM_G_VECTOR(OFS_PARM1);
468 move = (int)PRVM_G_FLOAT(OFS_PARM2);
469 ent = PRVM_G_EDICT(OFS_PARM3);
471 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]))
472 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));
474 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent);
476 prog->globals.server->trace_allsolid = trace.allsolid;
477 prog->globals.server->trace_startsolid = trace.startsolid;
478 prog->globals.server->trace_fraction = trace.fraction;
479 prog->globals.server->trace_inwater = trace.inwater;
480 prog->globals.server->trace_inopen = trace.inopen;
481 VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
482 VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
483 prog->globals.server->trace_plane_dist = trace.plane.dist;
485 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
487 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
488 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents)))
489 val->_float = trace.startsupercontents;
490 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents)))
491 val->_float = trace.hitsupercontents;
492 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags)))
493 val->_float = trace.hitq3surfaceflags;
494 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename)))
496 if (trace.hittexture)
498 char *s = VM_GetTempString();
499 strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH);
500 val->string = PRVM_SetEngineString(s);
512 Used for use tracing and shot targeting
513 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
514 if the tryents flag is set.
516 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
519 // LordHavoc: added this for my own use, VERY useful, similar to traceline
520 void PF_tracebox (void)
522 float *v1, *v2, *m1, *m2;
528 prog->xfunction->builtinsprofile += 30;
530 v1 = PRVM_G_VECTOR(OFS_PARM0);
531 m1 = PRVM_G_VECTOR(OFS_PARM1);
532 m2 = PRVM_G_VECTOR(OFS_PARM2);
533 v2 = PRVM_G_VECTOR(OFS_PARM3);
534 move = (int)PRVM_G_FLOAT(OFS_PARM4);
535 ent = PRVM_G_EDICT(OFS_PARM5);
537 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]))
538 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));
540 trace = SV_Move (v1, m1, m2, v2, move, ent);
542 prog->globals.server->trace_allsolid = trace.allsolid;
543 prog->globals.server->trace_startsolid = trace.startsolid;
544 prog->globals.server->trace_fraction = trace.fraction;
545 prog->globals.server->trace_inwater = trace.inwater;
546 prog->globals.server->trace_inopen = trace.inopen;
547 VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
548 VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
549 prog->globals.server->trace_plane_dist = trace.plane.dist;
551 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
553 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
554 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents)))
555 val->_float = trace.startsupercontents;
556 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents)))
557 val->_float = trace.hitsupercontents;
558 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags)))
559 val->_float = trace.hitq3surfaceflags;
560 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename)))
562 if (trace.hittexture)
564 char *s = VM_GetTempString();
565 strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH);
566 val->string = PRVM_SetEngineString(s);
573 extern trace_t SV_Trace_Toss (prvm_edict_t *ent, prvm_edict_t *ignore);
574 void PF_tracetoss (void)
578 prvm_edict_t *ignore;
581 prog->xfunction->builtinsprofile += 600;
583 ent = PRVM_G_EDICT(OFS_PARM0);
584 if (ent == prog->edicts)
586 VM_Warning("tracetoss: can not use world entity\n");
589 ignore = PRVM_G_EDICT(OFS_PARM1);
591 trace = SV_Trace_Toss (ent, ignore);
593 prog->globals.server->trace_allsolid = trace.allsolid;
594 prog->globals.server->trace_startsolid = trace.startsolid;
595 prog->globals.server->trace_fraction = trace.fraction;
596 prog->globals.server->trace_inwater = trace.inwater;
597 prog->globals.server->trace_inopen = trace.inopen;
598 VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
599 VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
600 prog->globals.server->trace_plane_dist = trace.plane.dist;
602 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
604 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
605 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents)))
606 val->_float = trace.startsupercontents;
607 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents)))
608 val->_float = trace.hitsupercontents;
609 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags)))
610 val->_float = trace.hitq3surfaceflags;
611 if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename)))
613 if (trace.hittexture)
615 char *s = VM_GetTempString();
616 strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH);
617 val->string = PRVM_SetEngineString(s);
629 Returns true if the given entity can move to the given position from it's
630 current position by walking or rolling.
632 scalar checkpos (entity, vector)
635 void PF_checkpos (void)
639 //============================================================================
642 unsigned char checkpvs[MAX_MAP_LEAFS/8];
644 int PF_newcheckclient (int check)
650 // cycle to the next one
652 check = bound(1, check, svs.maxclients);
653 if (check == svs.maxclients)
661 prog->xfunction->builtinsprofile++;
663 if (i == svs.maxclients+1)
665 // look up the client's edict
666 ent = PRVM_EDICT_NUM(i);
667 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
668 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
670 // found a valid client (possibly the same one again)
674 // get the PVS for the entity
675 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
677 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
678 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
687 Returns a client (or object that has a client enemy) that would be a
690 If there is more than one valid option, they are cycled each frame
692 If (self.origin + self.viewofs) is not in the PVS of the current target,
693 it is not returned at all.
698 int c_invis, c_notvis;
699 void PF_checkclient (void)
701 prvm_edict_t *ent, *self;
704 // find a new check if on a new frame
705 if (sv.time - sv.lastchecktime >= 0.1)
707 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
708 sv.lastchecktime = sv.time;
711 // return check if it might be visible
712 ent = PRVM_EDICT_NUM(sv.lastcheck);
713 if (ent->priv.server->free || ent->fields.server->health <= 0)
715 VM_RETURN_EDICT(prog->edicts);
719 // if current entity can't possibly see the check entity, return 0
720 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
721 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
722 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
725 VM_RETURN_EDICT(prog->edicts);
729 // might be able to see it
731 VM_RETURN_EDICT(ent);
734 //============================================================================
741 Sends text over to the client's execution buffer
743 stuffcmd (clientent, value, ...)
746 void PF_stuffcmd (void)
750 char string[VM_STRINGTEMP_LENGTH];
752 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
753 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
755 VM_Warning("Can't stuffcmd to a non-client\n");
759 VM_VarString(1, string, sizeof(string));
762 host_client = svs.clients + entnum-1;
763 Host_ClientCommands ("%s", string);
771 Returns a chain of entities that have origins within a spherical area
773 findradius (origin, radius)
776 void PF_findradius (void)
778 prvm_edict_t *ent, *chain;
779 vec_t radius, radius2;
780 vec3_t org, eorg, mins, maxs;
783 prvm_edict_t *touchedicts[MAX_EDICTS];
785 chain = (prvm_edict_t *)prog->edicts;
787 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
788 radius = PRVM_G_FLOAT(OFS_PARM1);
789 radius2 = radius * radius;
791 mins[0] = org[0] - (radius + 1);
792 mins[1] = org[1] - (radius + 1);
793 mins[2] = org[2] - (radius + 1);
794 maxs[0] = org[0] + (radius + 1);
795 maxs[1] = org[1] + (radius + 1);
796 maxs[2] = org[2] + (radius + 1);
797 numtouchedicts = SV_EntitiesInBox(mins, maxs, MAX_EDICTS, touchedicts);
798 if (numtouchedicts > MAX_EDICTS)
800 // this never happens
801 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
802 numtouchedicts = MAX_EDICTS;
804 for (i = 0;i < numtouchedicts;i++)
806 ent = touchedicts[i];
807 prog->xfunction->builtinsprofile++;
808 // Quake did not return non-solid entities but darkplaces does
809 // (note: this is the reason you can't blow up fallen zombies)
810 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
812 // LordHavoc: compare against bounding box rather than center so it
813 // doesn't miss large objects, and use DotProduct instead of Length
814 // for a major speedup
815 VectorSubtract(org, ent->fields.server->origin, eorg);
816 if (sv_gameplayfix_findradiusdistancetobox.integer)
818 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
819 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
820 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
823 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
824 if (DotProduct(eorg, eorg) < radius2)
826 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
831 VM_RETURN_EDICT(chain);
834 void PF_precache_file (void)
835 { // precache_file is only used to copy files with qcc, it does nothing
836 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
840 void PF_precache_sound (void)
842 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
843 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
846 void PF_precache_model (void)
848 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
849 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
856 float(float yaw, float dist) walkmove
859 void PF_walkmove (void)
867 // assume failure if it returns early
868 PRVM_G_FLOAT(OFS_RETURN) = 0;
870 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
871 if (ent == prog->edicts)
873 VM_Warning("walkmove: can not modify world entity\n");
876 if (ent->priv.server->free)
878 VM_Warning("walkmove: can not modify free entity\n");
881 yaw = PRVM_G_FLOAT(OFS_PARM0);
882 dist = PRVM_G_FLOAT(OFS_PARM1);
884 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
887 yaw = yaw*M_PI*2 / 360;
889 move[0] = cos(yaw)*dist;
890 move[1] = sin(yaw)*dist;
893 // save program state, because SV_movestep may call other progs
894 oldf = prog->xfunction;
895 oldself = prog->globals.server->self;
897 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
900 // restore program state
901 prog->xfunction = oldf;
902 prog->globals.server->self = oldself;
912 void PF_droptofloor (void)
918 // assume failure if it returns early
919 PRVM_G_FLOAT(OFS_RETURN) = 0;
921 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
922 if (ent == prog->edicts)
924 VM_Warning("droptofloor: can not modify world entity\n");
927 if (ent->priv.server->free)
929 VM_Warning("droptofloor: can not modify free entity\n");
933 VectorCopy (ent->fields.server->origin, end);
936 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
938 if (trace.fraction != 1)
940 VectorCopy (trace.endpos, ent->fields.server->origin);
941 SV_LinkEdict (ent, false);
942 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
943 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
944 PRVM_G_FLOAT(OFS_RETURN) = 1;
945 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
946 ent->priv.server->suspendedinairflag = true;
954 void(float style, string value) lightstyle
957 void PF_lightstyle (void)
964 style = (int)PRVM_G_FLOAT(OFS_PARM0);
965 val = PRVM_G_STRING(OFS_PARM1);
967 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
968 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
971 // change the string in sv
972 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
974 // send message to all clients on this server
975 if (sv.state != ss_active)
978 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
980 if (client->active && client->netconnection)
982 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
983 MSG_WriteChar (&client->netconnection->message,style);
984 MSG_WriteString (&client->netconnection->message, val);
994 void PF_checkbottom (void)
996 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1004 void PF_pointcontents (void)
1006 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1013 Pick a vector for the player to shoot along
1014 vector aim(entity, missilespeed)
1019 prvm_edict_t *ent, *check, *bestent;
1020 vec3_t start, dir, end, bestdir;
1023 float dist, bestdist;
1026 // assume failure if it returns early
1027 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1028 // if sv_aim is so high it can't possibly accept anything, skip out early
1029 if (sv_aim.value >= 1)
1032 ent = PRVM_G_EDICT(OFS_PARM0);
1033 if (ent == prog->edicts)
1035 VM_Warning("aim: can not use world entity\n");
1038 if (ent->priv.server->free)
1040 VM_Warning("aim: can not use free entity\n");
1043 speed = PRVM_G_FLOAT(OFS_PARM1);
1045 VectorCopy (ent->fields.server->origin, start);
1048 // try sending a trace straight
1049 VectorCopy (prog->globals.server->v_forward, dir);
1050 VectorMA (start, 2048, dir, end);
1051 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1052 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1053 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1055 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1060 // try all possible entities
1061 VectorCopy (dir, bestdir);
1062 bestdist = sv_aim.value;
1065 check = PRVM_NEXT_EDICT(prog->edicts);
1066 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1068 prog->xfunction->builtinsprofile++;
1069 if (check->fields.server->takedamage != DAMAGE_AIM)
1073 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1074 continue; // don't aim at teammate
1075 for (j=0 ; j<3 ; j++)
1076 end[j] = check->fields.server->origin[j]
1077 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1078 VectorSubtract (end, start, dir);
1079 VectorNormalize (dir);
1080 dist = DotProduct (dir, prog->globals.server->v_forward);
1081 if (dist < bestdist)
1082 continue; // to far to turn
1083 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1084 if (tr.ent == check)
1085 { // can shoot at this one
1093 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1094 dist = DotProduct (dir, prog->globals.server->v_forward);
1095 VectorScale (prog->globals.server->v_forward, dist, end);
1097 VectorNormalize (end);
1098 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1102 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1110 This was a major timewaster in progs, so it was converted to C
1113 void PF_changeyaw (void)
1116 float ideal, current, move, speed;
1118 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1119 if (ent == prog->edicts)
1121 VM_Warning("changeyaw: can not modify world entity\n");
1124 if (ent->priv.server->free)
1126 VM_Warning("changeyaw: can not modify free entity\n");
1129 current = ANGLEMOD(ent->fields.server->angles[1]);
1130 ideal = ent->fields.server->ideal_yaw;
1131 speed = ent->fields.server->yaw_speed;
1133 if (current == ideal)
1135 move = ideal - current;
1136 if (ideal > current)
1157 ent->fields.server->angles[1] = ANGLEMOD (current + move);
1165 void PF_changepitch (void)
1168 float ideal, current, move, speed;
1171 ent = PRVM_G_EDICT(OFS_PARM0);
1172 if (ent == prog->edicts)
1174 VM_Warning("changepitch: can not modify world entity\n");
1177 if (ent->priv.server->free)
1179 VM_Warning("changepitch: can not modify free entity\n");
1182 current = ANGLEMOD( ent->fields.server->angles[0] );
1183 if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1184 ideal = val->_float;
1187 VM_Warning("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch\n");
1190 if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1191 speed = val->_float;
1194 VM_Warning("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch\n");
1198 if (current == ideal)
1200 move = ideal - current;
1201 if (ideal > current)
1222 ent->fields.server->angles[0] = ANGLEMOD (current + move);
1226 ===============================================================================
1230 ===============================================================================
1233 #define MSG_BROADCAST 0 // unreliable to all
1234 #define MSG_ONE 1 // reliable to one (msg_entity)
1235 #define MSG_ALL 2 // reliable to all
1236 #define MSG_INIT 3 // write to the init string
1237 #define MSG_ENTITY 5
1239 sizebuf_t *WriteDest (void)
1244 extern sizebuf_t *sv2csqcbuf;
1246 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1250 return &sv.datagram;
1253 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1254 entnum = PRVM_NUM_FOR_EDICT(ent);
1255 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1257 VM_Warning ("WriteDest: tried to write to non-client\n");
1258 return &sv.reliable_datagram;
1261 return &svs.clients[entnum-1].netconnection->message;
1264 VM_Warning ("WriteDest: bad destination\n");
1266 return &sv.reliable_datagram;
1278 void PF_WriteByte (void)
1280 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1283 void PF_WriteChar (void)
1285 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1288 void PF_WriteShort (void)
1290 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1293 void PF_WriteLong (void)
1295 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1298 void PF_WriteAngle (void)
1300 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1303 void PF_WriteCoord (void)
1305 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1308 void PF_WriteString (void)
1310 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1313 void PF_WriteUnterminatedString (void)
1315 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1319 void PF_WriteEntity (void)
1321 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1324 //////////////////////////////////////////////////////////
1326 void PF_makestatic (void)
1331 ent = PRVM_G_EDICT(OFS_PARM0);
1332 if (ent == prog->edicts)
1334 VM_Warning("makestatic: can not modify world entity\n");
1337 if (ent->priv.server->free)
1339 VM_Warning("makestatic: can not modify free entity\n");
1344 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1349 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1350 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1351 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1355 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1356 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1357 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1360 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1361 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1362 for (i=0 ; i<3 ; i++)
1364 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1365 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1368 // throw the entity away now
1372 //=============================================================================
1379 void PF_setspawnparms (void)
1385 ent = PRVM_G_EDICT(OFS_PARM0);
1386 i = PRVM_NUM_FOR_EDICT(ent);
1387 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1389 Con_Print("tried to setspawnparms on a non-client\n");
1393 // copy spawn parms out of the client_t
1394 client = svs.clients + i-1;
1395 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1396 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1403 Returns a color vector indicating the lighting at the requested point.
1405 (Internal Operation note: actually measures the light beneath the point, just like
1406 the model lighting on the client)
1411 void PF_getlight (void)
1413 vec3_t ambientcolor, diffusecolor, diffusenormal;
1415 p = PRVM_G_VECTOR(OFS_PARM0);
1416 VectorClear(ambientcolor);
1417 VectorClear(diffusecolor);
1418 VectorClear(diffusenormal);
1419 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1420 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1421 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1424 void PF_registercvar (void)
1426 const char *name, *value;
1427 name = PRVM_G_STRING(OFS_PARM0);
1428 value = PRVM_G_STRING(OFS_PARM1);
1429 PRVM_G_FLOAT(OFS_RETURN) = 0;
1431 // first check to see if it has already been defined
1432 if (Cvar_FindVar (name))
1435 // check for overlap with a command
1436 if (Cmd_Exists (name))
1438 VM_Warning("PF_registercvar: %s is a command\n", name);
1442 Cvar_Get(name, value, 0);
1444 PRVM_G_FLOAT(OFS_RETURN) = 1; // success
1449 unsigned char type; // 1/2/8 or other value if isn't used
1453 static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
1454 static int vm_autosentstats_last;
1456 void VM_AutoSentStats_Clear (void)
1458 if(vm_autosentstats)
1460 Z_Free(vm_autosentstats);
1461 vm_autosentstats = NULL;
1462 vm_autosentstats_last = -1;
1466 //[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
1467 #define VM_SENDSTAT(a,b,c)\
1470 if((c)==(unsigned char)(c))\
1472 MSG_WriteByte((a), svc_updatestatubyte);\
1473 MSG_WriteByte((a), (b));\
1474 MSG_WriteByte((a), (c));\
1478 MSG_WriteByte((a), svc_updatestat);\
1479 MSG_WriteByte((a), (b));\
1480 MSG_WriteLong((a), (c));\
1484 void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1496 if(!vm_autosentstats)
1499 send = (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5);
1501 for(i=0; i<vm_autosentstats_last+1 ;i++)
1503 if(!vm_autosentstats[i].type)
1505 switch(vm_autosentstats[i].type)
1509 t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
1517 stats[i+32] = si[0];
1518 stats[i+33] = si[1];
1519 stats[i+34] = si[2];
1520 stats[i+35] = si[3];
1524 VM_SENDSTAT(msg, i+32, si[0]);
1525 VM_SENDSTAT(msg, i+33, si[1]);
1526 VM_SENDSTAT(msg, i+34, si[2]);
1527 VM_SENDSTAT(msg, i+35, si[3]);
1533 k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1534 k.i = LittleLong (k.i);
1538 VM_SENDSTAT(msg, i+32, k.i);
1542 v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1546 VM_SENDSTAT(msg, i+32, v);
1554 // void(float index, float type, .void field) SV_AddStat = #470;
1555 // Set up an auto-sent player stat.
1556 // Client's get thier own fields sent to them. Index may not be less than 32.
1557 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1558 // 1: string (4 stats carrying a total of 16 charactures)
1559 // 2: float (one stat, float converted to an integer for transportation)
1560 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1561 void PF_SV_AddStat (void)
1566 if(!vm_autosentstats)
1568 vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
1569 if(!vm_autosentstats)
1571 VM_Warning("PF_SV_AddStat: not enough memory\n");
1575 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1576 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1577 off = PRVM_G_INT (OFS_PARM2);
1582 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1585 if(i >= (MAX_CL_STATS-32))
1587 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1590 if(i > (MAX_CL_STATS-32-4) && type == 1)
1592 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1595 vm_autosentstats[i].type = type;
1596 vm_autosentstats[i].fieldoffset = off;
1597 if(vm_autosentstats_last < i)
1598 vm_autosentstats_last = i;
1605 copies data from one entity to another
1607 copyentity(src, dst)
1610 void PF_copyentity (void)
1612 prvm_edict_t *in, *out;
1613 in = PRVM_G_EDICT(OFS_PARM0);
1614 if (in == prog->edicts)
1616 VM_Warning("copyentity: can not read world entity\n");
1619 if (in->priv.server->free)
1621 VM_Warning("copyentity: can not read free entity\n");
1624 out = PRVM_G_EDICT(OFS_PARM1);
1625 if (out == prog->edicts)
1627 VM_Warning("copyentity: can not modify world entity\n");
1630 if (out->priv.server->free)
1632 VM_Warning("copyentity: can not modify free entity\n");
1635 memcpy(out->fields.server, in->fields.server, prog->progs->entityfields * 4);
1643 sets the color of a client and broadcasts the update to all connected clients
1645 setcolor(clientent, value)
1648 void PF_setcolor (void)
1654 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1655 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1657 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1659 Con_Print("tried to setcolor a non-client\n");
1663 client = svs.clients + entnum-1;
1666 if ((val = PRVM_GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
1668 client->edict->fields.server->team = (i & 15) + 1;
1671 if (client->old_colors != client->colors)
1673 client->old_colors = client->colors;
1674 // send notification to all clients
1675 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1676 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1677 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1685 effect(origin, modelname, startframe, framecount, framerate)
1688 void PF_effect (void)
1692 s = PRVM_G_STRING(OFS_PARM1);
1695 VM_Warning("effect: no model specified\n");
1699 i = SV_ModelIndex(s, 1);
1702 VM_Warning("effect: model not precached\n");
1705 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));
1708 void PF_te_blood (void)
1710 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1712 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1713 MSG_WriteByte(&sv.datagram, TE_BLOOD);
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_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1720 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1721 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1723 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1726 void PF_te_bloodshower (void)
1728 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1730 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1731 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1733 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1734 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1735 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1741 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1743 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1746 void PF_te_explosionrgb (void)
1748 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1749 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1751 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1752 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1753 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1755 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1756 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1757 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1760 void PF_te_particlecube (void)
1762 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1764 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1765 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1771 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1772 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1773 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1775 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1776 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1777 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1779 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1781 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1782 // gravity true/false
1783 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1785 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1788 void PF_te_particlerain (void)
1790 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1792 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1793 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1795 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1796 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1797 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1799 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1800 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1801 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1803 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1807 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1809 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1812 void PF_te_particlesnow (void)
1814 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1816 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1817 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1823 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1825 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1827 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1831 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1833 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1836 void PF_te_spark (void)
1838 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1840 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1841 MSG_WriteByte(&sv.datagram, TE_SPARK);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1845 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1847 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1848 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1849 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1851 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1854 void PF_te_gunshotquad (void)
1856 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1857 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1864 void PF_te_spikequad (void)
1866 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1867 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1874 void PF_te_superspikequad (void)
1876 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1877 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1884 void PF_te_explosionquad (void)
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);
1894 void PF_te_smallflash (void)
1896 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1897 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1904 void PF_te_customflash (void)
1906 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1908 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1909 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1911 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1915 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1917 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1919 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1920 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1921 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1924 void PF_te_gunshot (void)
1926 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1927 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1929 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1934 void PF_te_spike (void)
1936 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1937 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1944 void PF_te_superspike (void)
1946 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1947 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1954 void PF_te_explosion (void)
1956 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1957 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
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);
1964 void PF_te_tarexplosion (void)
1966 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1967 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1974 void PF_te_wizspike (void)
1976 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1977 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1984 void PF_te_knightspike (void)
1986 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1987 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1994 void PF_te_lavasplash (void)
1996 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1997 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2004 void PF_te_teleport (void)
2006 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2007 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2010 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2014 void PF_te_explosion2 (void)
2016 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2017 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
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);
2023 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2024 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2027 void PF_te_lightning1 (void)
2029 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2030 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2032 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2034 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2035 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2036 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2038 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2039 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2040 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2043 void PF_te_lightning2 (void)
2045 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2046 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2048 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2050 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2051 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2055 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2059 void PF_te_lightning3 (void)
2061 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2062 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2064 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2067 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2070 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2071 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2072 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2075 void PF_te_beam (void)
2077 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2078 MSG_WriteByte(&sv.datagram, TE_BEAM);
2080 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2082 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2083 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2084 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2086 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2087 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2088 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2091 void PF_te_plasmaburn (void)
2093 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2094 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2095 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2096 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2100 void PF_te_flamejet (void)
2102 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2103 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2105 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2106 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2107 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2109 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2110 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2111 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2113 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2116 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2119 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2121 bestdist = 1000000000;
2123 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2125 // clip original point to each triangle of the surface and find the
2126 // triangle that is closest
2127 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2128 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2129 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2130 TriangleNormal(v[0], v[1], v[2], facenormal);
2131 VectorNormalize(facenormal);
2132 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2133 VectorMA(p, offsetdist, facenormal, temp);
2134 for (j = 0, k = 2;j < 3;k = j, j++)
2136 VectorSubtract(v[k], v[j], edgenormal);
2137 CrossProduct(edgenormal, facenormal, sidenormal);
2138 VectorNormalize(sidenormal);
2139 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2141 VectorMA(temp, offsetdist, sidenormal, temp);
2143 dist = VectorDistance2(temp, p);
2144 if (bestdist > dist)
2147 VectorCopy(temp, out);
2152 static model_t *getmodel(prvm_edict_t *ed)
2155 if (!ed || ed->priv.server->free)
2157 modelindex = (int)ed->fields.server->modelindex;
2158 if (modelindex < 1 || modelindex >= MAX_MODELS)
2160 return sv.models[modelindex];
2163 static msurface_t *getsurface(model_t *model, int surfacenum)
2165 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2167 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2171 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2172 void PF_getsurfacenumpoints(void)
2175 msurface_t *surface;
2176 // return 0 if no such surface
2177 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2179 PRVM_G_FLOAT(OFS_RETURN) = 0;
2183 // note: this (incorrectly) assumes it is a simple polygon
2184 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2186 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2187 void PF_getsurfacepoint(void)
2191 msurface_t *surface;
2193 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2194 ed = PRVM_G_EDICT(OFS_PARM0);
2195 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2197 // note: this (incorrectly) assumes it is a simple polygon
2198 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2199 if (pointnum < 0 || pointnum >= surface->num_vertices)
2201 // FIXME: implement rotation/scaling
2202 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2204 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2205 void PF_getsurfacenormal(void)
2208 msurface_t *surface;
2210 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2211 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2213 // FIXME: implement rotation/scaling
2214 // note: this (incorrectly) assumes it is a simple polygon
2215 // note: this only returns the first triangle, so it doesn't work very
2216 // well for curved surfaces or arbitrary meshes
2217 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);
2218 VectorNormalize(normal);
2219 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2221 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2222 void PF_getsurfacetexture(void)
2225 msurface_t *surface;
2226 PRVM_G_INT(OFS_RETURN) = 0;
2227 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2229 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(surface->texture->name);
2231 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2232 void PF_getsurfacenearpoint(void)
2234 int surfacenum, best;
2236 vec_t dist, bestdist;
2239 msurface_t *surface;
2241 PRVM_G_FLOAT(OFS_RETURN) = -1;
2242 ed = PRVM_G_EDICT(OFS_PARM0);
2243 point = PRVM_G_VECTOR(OFS_PARM1);
2245 if (!ed || ed->priv.server->free)
2247 model = getmodel(ed);
2248 if (!model || !model->num_surfaces)
2251 // FIXME: implement rotation/scaling
2252 VectorSubtract(point, ed->fields.server->origin, p);
2254 bestdist = 1000000000;
2255 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2257 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2258 // first see if the nearest point on the surface's box is closer than the previous match
2259 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2260 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2261 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2262 dist = VectorLength2(clipped);
2263 if (dist < bestdist)
2265 // it is, check the nearest point on the actual geometry
2266 clippointtosurface(model, surface, p, clipped);
2267 VectorSubtract(clipped, p, clipped);
2268 dist += VectorLength2(clipped);
2269 if (dist < bestdist)
2271 // that's closer too, store it as the best match
2277 PRVM_G_FLOAT(OFS_RETURN) = best;
2279 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2280 void PF_getsurfaceclippedpoint(void)
2284 msurface_t *surface;
2286 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2287 ed = PRVM_G_EDICT(OFS_PARM0);
2288 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2290 // FIXME: implement rotation/scaling
2291 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2292 clippointtosurface(model, surface, p, out);
2293 // FIXME: implement rotation/scaling
2294 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2297 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2298 //this function originally written by KrimZon, made shorter by LordHavoc
2299 void PF_clientcommand (void)
2301 client_t *temp_client;
2304 //find client for this entity
2305 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2306 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2308 Con_Print("PF_clientcommand: entity is not a client\n");
2312 temp_client = host_client;
2313 host_client = svs.clients + i;
2314 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2315 host_client = temp_client;
2318 //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)
2319 void PF_setattachment (void)
2321 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2322 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2323 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2328 if (e == prog->edicts)
2330 VM_Warning("setattachment: can not modify world entity\n");
2333 if (e->priv.server->free)
2335 VM_Warning("setattachment: can not modify free entity\n");
2339 if (tagentity == NULL)
2340 tagentity = prog->edicts;
2342 v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_entity);
2344 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2346 v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_index);
2349 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2351 modelindex = (int)tagentity->fields.server->modelindex;
2352 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2354 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2356 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);
2359 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));
2363 /////////////////////////////////////////
2364 // DP_MD3_TAGINFO extension coded by VorteX
2366 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2371 i = (int)e->fields.server->modelindex;
2372 if (i < 1 || i >= MAX_MODELS)
2374 model = sv.models[i];
2376 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2379 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2381 float scale = PRVM_GETEDICTFIELDVALUE(ent, eval_scale)->_float;
2385 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);
2387 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 * 0.333);
2390 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2396 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2397 && (model = sv.models[(int)ent->fields.server->modelindex])
2398 && model->animscenes)
2400 // if model has wrong frame, engine automatically switches to model first frame
2401 frame = (int)ent->fields.server->frame;
2402 if (frame < 0 || frame >= model->numframes)
2404 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2406 *out = identitymatrix;
2410 // Warnings/errors code:
2411 // 0 - normal (everything all-right)
2414 // 3 - null or non-precached model
2415 // 4 - no tags with requested index
2416 // 5 - runaway loop at attachment chain
2417 extern cvar_t cl_bob;
2418 extern cvar_t cl_bobcycle;
2419 extern cvar_t cl_bobup;
2420 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2424 int modelindex, attachloop;
2425 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2428 *out = identitymatrix; // warnings and errors return identical matrix
2430 if (ent == prog->edicts)
2432 if (ent->priv.server->free)
2435 modelindex = (int)ent->fields.server->modelindex;
2436 if (modelindex <= 0 || modelindex > MAX_MODELS)
2439 model = sv.models[modelindex];
2441 tagmatrix = identitymatrix;
2442 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2446 if (attachloop >= 256) // prevent runaway looping
2448 // apply transformation by child's tagindex on parent entity and then
2449 // by parent entity itself
2450 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2451 if (ret && attachloop == 0)
2453 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2454 SV_GetEntityMatrix(ent, &entitymatrix, false);
2455 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2456 // next iteration we process the parent entity
2457 if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict)
2459 tagindex = (int)PRVM_GETEDICTFIELDVALUE(ent, eval_tag_index)->_float;
2460 ent = PRVM_EDICT_NUM(val->edict);
2467 // RENDER_VIEWMODEL magic
2468 if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
2470 Matrix4x4_Copy(&tagmatrix, out);
2471 ent = PRVM_EDICT_NUM(val->edict);
2473 SV_GetEntityMatrix(ent, &entitymatrix, true);
2474 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2477 // Cl_bob, ported from rendering code
2478 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2481 // LordHavoc: this code is *weird*, but not replacable (I think it
2482 // should be done in QC on the server, but oh well, quake is quake)
2483 // LordHavoc: figured out bobup: the time at which the sin is at 180
2484 // degrees (which allows lengthening or squishing the peak or valley)
2485 cycle = sv.time/cl_bobcycle.value;
2486 cycle -= (int)cycle;
2487 if (cycle < cl_bobup.value)
2488 cycle = sin(M_PI * cycle / cl_bobup.value);
2490 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2491 // bob is proportional to velocity in the xy plane
2492 // (don't count Z, or jumping messes it up)
2493 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;
2494 bob = bob*0.3 + bob*0.7*cycle;
2495 out->m[2][3] += bound(-7, bob, 4);
2502 //float(entity ent, string tagname) gettagindex;
2504 void PF_gettagindex (void)
2506 prvm_edict_t *ent = PRVM_G_EDICT(OFS_PARM0);
2507 const char *tag_name = PRVM_G_STRING(OFS_PARM1);
2508 int modelindex, tag_index;
2510 if (ent == prog->edicts)
2512 VM_Warning("gettagindex: can't affect world entity\n");
2515 if (ent->priv.server->free)
2517 VM_Warning("gettagindex: can't affect free entity\n");
2521 modelindex = (int)ent->fields.server->modelindex;
2523 if (modelindex <= 0 || modelindex > MAX_MODELS)
2524 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2527 tag_index = SV_GetTagIndex(ent, tag_name);
2529 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2531 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2534 //vector(entity ent, float tagindex) gettaginfo;
2535 void PF_gettaginfo (void)
2537 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2538 int tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2539 matrix4x4_t tag_matrix;
2542 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2543 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2548 VM_Warning("gettagindex: can't affect world entity\n");
2551 VM_Warning("gettagindex: can't affect free entity\n");
2554 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2557 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2560 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2565 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2566 void PF_dropclient (void)
2569 client_t *oldhostclient;
2570 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2571 if (clientnum < 0 || clientnum >= svs.maxclients)
2573 VM_Warning("dropclient: not a client\n");
2576 if (!svs.clients[clientnum].active)
2578 VM_Warning("dropclient: that client slot is not connected\n");
2581 oldhostclient = host_client;
2582 host_client = svs.clients + clientnum;
2583 SV_DropClient(false);
2584 host_client = oldhostclient;
2587 //entity() spawnclient (DP_SV_BOTCLIENT)
2588 void PF_spawnclient (void)
2592 prog->xfunction->builtinsprofile += 2;
2594 for (i = 0;i < svs.maxclients;i++)
2596 if (!svs.clients[i].active)
2598 prog->xfunction->builtinsprofile += 100;
2599 SV_ConnectClient (i, NULL);
2600 // this has to be set or else ClientDisconnect won't be called
2601 // we assume the qc will call ClientConnect...
2602 svs.clients[i].clientconnectcalled = true;
2603 ed = PRVM_EDICT_NUM(i + 1);
2607 VM_RETURN_EDICT(ed);
2610 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2611 void PF_clienttype (void)
2614 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2615 if (clientnum < 0 || clientnum >= svs.maxclients)
2616 PRVM_G_FLOAT(OFS_RETURN) = 3;
2617 else if (!svs.clients[clientnum].active)
2618 PRVM_G_FLOAT(OFS_RETURN) = 0;
2619 else if (svs.clients[clientnum].netconnection)
2620 PRVM_G_FLOAT(OFS_RETURN) = 1;
2622 PRVM_G_FLOAT(OFS_RETURN) = 2;
2625 void PF_edict_num (void)
2627 VM_RETURN_EDICT(PRVM_EDICT_NUM((int)PRVM_G_FLOAT(OFS_PARM0)));
2630 prvm_builtin_t vm_sv_builtins[] = {
2632 PF_makevectors, // #1 void(vector ang) makevectors
2633 PF_setorigin, // #2 void(entity e, vector o) setorigin
2634 PF_setmodel, // #3 void(entity e, string m) setmodel
2635 PF_setsize, // #4 void(entity e, vector min, vector max) setsize
2636 NULL, // #5 void(entity e, vector min, vector max) setabssize
2637 VM_break, // #6 void() break
2638 VM_random, // #7 float() random
2639 PF_sound, // #8 void(entity e, float chan, string samp) sound
2640 VM_normalize, // #9 vector(vector v) normalize
2641 VM_error, // #10 void(string e) error
2642 VM_objerror, // #11 void(string e) objerror
2643 VM_vlen, // #12 float(vector v) vlen
2644 VM_vectoyaw, // #13 float(vector v) vectoyaw
2645 VM_spawn, // #14 entity() spawn
2646 VM_remove, // #15 void(entity e) remove
2647 PF_traceline, // #16 float(vector v1, vector v2, float tryents) traceline
2648 PF_checkclient, // #17 entity() clientlist
2649 VM_find, // #18 entity(entity start, .string fld, string match) find
2650 PF_precache_sound, // #19 void(string s) precache_sound
2651 PF_precache_model, // #20 void(string s) precache_model
2652 PF_stuffcmd, // #21 void(entity client, string s)stuffcmd
2653 PF_findradius, // #22 entity(vector org, float rad) findradius
2654 VM_bprint, // #23 void(string s) bprint
2655 PF_sprint, // #24 void(entity client, string s) sprint
2656 VM_dprint, // #25 void(string s) dprint
2657 VM_ftos, // #26 void(string s) ftos
2658 VM_vtos, // #27 void(string s) vtos
2659 VM_coredump, // #28 void() coredump
2660 VM_traceon, // #29 void() traceon
2661 VM_traceoff, // #30 void() traceoff
2662 VM_eprint, // #31 void(entity e) eprint
2663 PF_walkmove, // #32 float(float yaw, float dist) walkmove
2665 PF_droptofloor, // #34 float() droptofloor
2666 PF_lightstyle, // #35 void(float style, string value) lightstyle
2667 VM_rint, // #36 float(float v) rint
2668 VM_floor, // #37 float(float v) floor
2669 VM_ceil, // #38 float(float v) ceil
2671 PF_checkbottom, // #40 float(entity e) checkbottom
2672 PF_pointcontents, // #41 float(vector v) pointcontents
2674 VM_fabs, // #43 float(float f) fabs
2675 PF_aim, // #44 vector(entity e, float speed) aim
2676 VM_cvar, // #45 float(string s) cvar
2677 VM_localcmd, // #46 void(string s) localcmd
2678 VM_nextent, // #47 entity(entity e) nextent
2679 PF_particle, // #48 void(vector o, vector d, float color, float count) particle
2680 PF_changeyaw, // #49 void() ChangeYaw
2682 VM_vectoangles, // #51 vector(vector v) vectoangles
2683 PF_WriteByte, // #52 void(float to, float f) WriteByte
2684 PF_WriteChar, // #53 void(float to, float f) WriteChar
2685 PF_WriteShort, // #54 void(float to, float f) WriteShort
2686 PF_WriteLong, // #55 void(float to, float f) WriteLong
2687 PF_WriteCoord, // #56 void(float to, float f) WriteCoord
2688 PF_WriteAngle, // #57 void(float to, float f) WriteAngle
2689 PF_WriteString, // #58 void(float to, string s) WriteString
2690 PF_WriteEntity, // #59 void(float to, entity e) WriteEntity
2691 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
2692 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
2693 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
2694 PF_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
2695 PF_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
2696 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS)
2698 SV_MoveToGoal, // #67 void(float step) movetogoal
2699 PF_precache_file, // #68 string(string s) precache_file
2700 PF_makestatic, // #69 void(entity e) makestatic
2701 VM_changelevel, // #70 void(string s) changelevel
2703 VM_cvar_set, // #72 void(string var, string val) cvar_set
2704 PF_centerprint, // #73 void(entity client, strings) centerprint
2705 PF_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound
2706 PF_precache_model, // #75 string(string s) precache_model2
2707 PF_precache_sound, // #76 string(string s) precache_sound2
2708 PF_precache_file, // #77 string(string s) precache_file2
2709 PF_setspawnparms, // #78 void(entity e) setspawnparms
2712 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2721 PF_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2722 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2723 PF_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2724 PF_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2725 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2726 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2727 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2728 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2729 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2730 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2741 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2742 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2743 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2744 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2745 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2746 VM_strcat, // #115 string(string s1, string s2) strcat (FRIK_FILE)
2747 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2748 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2749 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2750 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2751 e10, e10, e10, e10, e10, e10, e10, e10, // #120-199
2752 // FTEQW range #200-#299
2771 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2781 e10, e10, e10, e10, e10, e10, e10, e10, e10, e10, // #300-399
2782 VM_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
2783 PF_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
2784 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
2785 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
2786 PF_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
2787 PF_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
2788 PF_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
2789 PF_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
2790 PF_te_particlecube, // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
2791 PF_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
2792 PF_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
2793 PF_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
2794 PF_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
2795 PF_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
2796 PF_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
2797 PF_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
2798 PF_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
2799 PF_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
2800 PF_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
2801 PF_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
2802 PF_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
2803 PF_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
2804 PF_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
2805 PF_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
2806 PF_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
2807 PF_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
2808 PF_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
2809 PF_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
2810 PF_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
2811 PF_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
2812 PF_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
2813 PF_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
2814 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
2815 PF_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
2816 PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
2817 PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
2818 PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
2819 PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
2820 PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
2821 PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
2822 PF_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
2823 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
2824 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
2825 PF_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
2826 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
2827 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
2828 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
2829 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
2830 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
2831 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
2832 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
2833 PF_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
2834 PF_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
2835 PF_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
2836 PF_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
2837 PF_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
2838 PF_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
2839 PF_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
2841 PF_edict_num, // #459 entity(float num) (??)
2842 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
2843 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
2844 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
2845 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
2846 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
2847 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
2848 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
2849 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
2850 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
2851 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
2852 PF_SV_AddStat, // #470 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2862 e10, e10 // #480-499 (LordHavoc)
2865 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
2867 void VM_SV_Cmd_Init(void)
2872 void VM_SV_Cmd_Reset(void)