6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
37 "DP_ENT_CUSTOMCOLORMAP "
38 "DP_ENT_EXTERIORMODELTOCLIENT "
40 "DP_ENT_LOWPRECISION "
44 "DP_GFX_EXTERNALTEXTURES "
45 "DP_GFX_EXTERNALTEXTURES_PERMAP "
47 "DP_GFX_QUAKE3MODELTAGS "
51 "DP_HALFLIFE_MAP_CVAR "
57 "DP_MOVETYPEBOUNCEMISSILE "
60 "DP_QC_ASINACOSATANATAN2TAN "
65 "DP_QC_CVAR_DEFSTRING "
66 "DP_QC_CVAR_DESCRIPTION "
73 "DP_QC_FINDCHAINFLAGS "
74 "DP_QC_FINDCHAINFLOAT "
80 "DP_QC_GETSURFACEPOINTATTRIBUTE "
82 "DP_QC_GETTAGINFO_BONEPROPERTIES "
84 "DP_QC_MULTIPLETEMPSTRINGS "
85 "DP_QC_NUM_FOR_EDICT "
87 "DP_QC_SINCOSSQRTPOW "
89 "DP_QC_STRINGBUFFERS "
90 "DP_QC_STRINGBUFFERS_CVARLIST "
91 "DP_QC_STRINGCOLORFUNCTIONS "
92 "DP_QC_STRING_CASE_FUNCTIONS "
94 "DP_QC_TOKENIZEBYSEPARATOR "
95 "DP_QC_TOKENIZE_CONSOLE "
98 "DP_QC_TRACE_MOVETYPE_HITMODEL "
99 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
100 "DP_QC_UNLIMITEDTEMPSTRINGS "
103 "DP_QC_VECTOANGLES_WITH_ROLL "
104 "DP_QC_VECTORVECTORS "
111 "DP_SND_DIRECTIONLESSATTNNONE "
118 "DP_SV_CLIENTCOLORS "
121 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
122 "DP_SV_DRAWONLYTOCLIENT "
125 "DP_SV_ENTITYCONTENTSTRANSITION "
126 "DP_SV_MODELFLAGS_AS_EFFECTS "
127 "DP_SV_MOVETYPESTEP_LANDEVENT "
129 "DP_SV_NODRAWTOCLIENT "
130 "DP_SV_ONENTITYNOSPAWNFUNCTION "
131 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
133 "DP_SV_PLAYERPHYSICS "
134 "DP_SV_POINTPARTICLES "
136 "DP_SV_PRECACHEANYTIME "
140 "DP_SV_ROTATINGBMODEL "
144 "DP_SV_SPAWNFUNC_PREFIX "
145 "DP_SV_WRITEPICTURE "
146 "DP_SV_WRITEUNTERMINATEDSTRING "
150 "DP_TE_EXPLOSIONRGB "
152 "DP_TE_PARTICLECUBE "
153 "DP_TE_PARTICLERAIN "
154 "DP_TE_PARTICLESNOW "
156 "DP_TE_QUADEFFECTS1 "
159 "DP_TE_STANDARDEFFECTBUILTINS "
160 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
165 "KRIMZON_SV_PARSECLIENTCOMMAND "
168 "NEXUIZ_PLAYERMODEL "
170 "PRYDON_CLIENTCURSOR "
171 "TENEBRAE_GFX_DLIGHTS "
174 //"EXT_CSQC " // not ready yet
181 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.
183 setorigin (entity, origin)
186 static void VM_SV_setorigin (void)
191 VM_SAFEPARMCOUNT(2, VM_setorigin);
193 e = PRVM_G_EDICT(OFS_PARM0);
194 if (e == prog->edicts)
196 VM_Warning("setorigin: can not modify world entity\n");
199 if (e->priv.server->free)
201 VM_Warning("setorigin: can not modify free entity\n");
204 org = PRVM_G_VECTOR(OFS_PARM1);
205 VectorCopy (org, e->fields.server->origin);
206 SV_LinkEdict (e, false);
209 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
210 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
214 for (i=0 ; i<3 ; i++)
216 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
218 // set derived values
219 VectorCopy (min, e->fields.server->mins);
220 VectorCopy (max, e->fields.server->maxs);
221 VectorSubtract (max, min, e->fields.server->size);
223 SV_LinkEdict (e, false);
230 the size box is rotated by the current angle
231 LordHavoc: no it isn't...
233 setsize (entity, minvector, maxvector)
236 static void VM_SV_setsize (void)
241 VM_SAFEPARMCOUNT(3, VM_setsize);
243 e = PRVM_G_EDICT(OFS_PARM0);
244 if (e == prog->edicts)
246 VM_Warning("setsize: can not modify world entity\n");
249 if (e->priv.server->free)
251 VM_Warning("setsize: can not modify free entity\n");
254 min = PRVM_G_VECTOR(OFS_PARM1);
255 max = PRVM_G_VECTOR(OFS_PARM2);
256 SetMinMaxSize (e, min, max, false);
264 setmodel(entity, model)
267 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
268 static void VM_SV_setmodel (void)
274 VM_SAFEPARMCOUNT(2, VM_setmodel);
276 e = PRVM_G_EDICT(OFS_PARM0);
277 if (e == prog->edicts)
279 VM_Warning("setmodel: can not modify world entity\n");
282 if (e->priv.server->free)
284 VM_Warning("setmodel: can not modify free entity\n");
287 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
288 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
289 e->fields.server->modelindex = i;
295 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
296 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
298 SetMinMaxSize (e, quakemins, quakemaxs, true);
301 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
308 single print to a specific client
310 sprint(clientent, value)
313 static void VM_SV_sprint (void)
317 char string[VM_STRINGTEMP_LENGTH];
319 VM_VarString(1, string, sizeof(string));
321 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
323 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
324 // LordHavoc: div0 requested that sprintto world operate like print
331 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
333 VM_Warning("tried to centerprint to a non-client\n");
337 client = svs.clients + entnum-1;
338 if (!client->netconnection)
341 MSG_WriteChar(&client->netconnection->message,svc_print);
342 MSG_WriteString(&client->netconnection->message, string);
350 single print to a specific client
352 centerprint(clientent, value)
355 static void VM_SV_centerprint (void)
359 char string[VM_STRINGTEMP_LENGTH];
361 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
363 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
365 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
367 VM_Warning("tried to centerprint to a non-client\n");
371 client = svs.clients + entnum-1;
372 if (!client->netconnection)
375 VM_VarString(1, string, sizeof(string));
376 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
377 MSG_WriteString(&client->netconnection->message, string);
384 particle(origin, color, count)
387 static void VM_SV_particle (void)
393 VM_SAFEPARMCOUNT(4, VM_SV_particle);
395 org = PRVM_G_VECTOR(OFS_PARM0);
396 dir = PRVM_G_VECTOR(OFS_PARM1);
397 color = PRVM_G_FLOAT(OFS_PARM2);
398 count = PRVM_G_FLOAT(OFS_PARM3);
399 SV_StartParticle (org, dir, (int)color, (int)count);
409 static void VM_SV_ambientsound (void)
413 float vol, attenuation;
416 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
418 pos = PRVM_G_VECTOR (OFS_PARM0);
419 samp = PRVM_G_STRING(OFS_PARM1);
420 vol = PRVM_G_FLOAT(OFS_PARM2);
421 attenuation = PRVM_G_FLOAT(OFS_PARM3);
423 // check to see if samp was properly precached
424 soundnum = SV_SoundIndex(samp, 1);
432 // add an svc_spawnambient command to the level signon packet
435 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
437 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
439 MSG_WriteVector(&sv.signon, pos, sv.protocol);
441 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
442 MSG_WriteShort (&sv.signon, soundnum);
444 MSG_WriteByte (&sv.signon, soundnum);
446 MSG_WriteByte (&sv.signon, (int)(vol*255));
447 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
455 Each entity can have eight independant sound sources, like voice,
458 Channel 0 is an auto-allocate channel, the others override anything
459 already running on that entity/channel pair.
461 An attenuation of 0 will play full volume everywhere in the level.
462 Larger attenuations will drop off.
466 static void VM_SV_sound (void)
470 prvm_edict_t *entity;
474 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
476 entity = PRVM_G_EDICT(OFS_PARM0);
477 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
478 sample = PRVM_G_STRING(OFS_PARM2);
479 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
480 attenuation = PRVM_G_FLOAT(OFS_PARM4);
483 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
487 if (volume < 0 || volume > 255)
489 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
493 if (attenuation < 0 || attenuation > 4)
495 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
499 if (channel < 0 || channel > 7)
501 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
505 SV_StartSound (entity, channel, sample, volume, attenuation);
512 Follows the same logic as VM_SV_sound, except instead of
513 an entity, an origin for the sound is provided, and channel
514 is omitted (since no entity is being tracked).
518 static void VM_SV_pointsound(void)
525 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
527 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
528 sample = PRVM_G_STRING(OFS_PARM1);
529 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
530 attenuation = PRVM_G_FLOAT(OFS_PARM3);
532 if (volume < 0 || volume > 255)
534 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
538 if (attenuation < 0 || attenuation > 4)
540 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
544 SV_StartPointSound (org, sample, volume, attenuation);
551 Used for use tracing and shot targeting
552 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
553 if the tryents flag is set.
555 traceline (vector1, vector2, movetype, ignore)
558 static void VM_SV_traceline (void)
565 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
567 prog->xfunction->builtinsprofile += 30;
569 v1 = PRVM_G_VECTOR(OFS_PARM0);
570 v2 = PRVM_G_VECTOR(OFS_PARM1);
571 move = (int)PRVM_G_FLOAT(OFS_PARM2);
572 ent = PRVM_G_EDICT(OFS_PARM3);
574 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]))
575 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));
577 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
579 VM_SetTraceGlobals(&trace);
587 Used for use tracing and shot targeting
588 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
589 if the tryents flag is set.
591 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
594 // LordHavoc: added this for my own use, VERY useful, similar to traceline
595 static void VM_SV_tracebox (void)
597 float *v1, *v2, *m1, *m2;
602 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
604 prog->xfunction->builtinsprofile += 30;
606 v1 = PRVM_G_VECTOR(OFS_PARM0);
607 m1 = PRVM_G_VECTOR(OFS_PARM1);
608 m2 = PRVM_G_VECTOR(OFS_PARM2);
609 v2 = PRVM_G_VECTOR(OFS_PARM3);
610 move = (int)PRVM_G_FLOAT(OFS_PARM4);
611 ent = PRVM_G_EDICT(OFS_PARM5);
613 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]))
614 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));
616 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
618 VM_SetTraceGlobals(&trace);
621 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
626 vec3_t original_origin;
627 vec3_t original_velocity;
628 vec3_t original_angles;
629 vec3_t original_avelocity;
633 VectorCopy(tossent->fields.server->origin , original_origin );
634 VectorCopy(tossent->fields.server->velocity , original_velocity );
635 VectorCopy(tossent->fields.server->angles , original_angles );
636 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
638 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
639 if (val != NULL && val->_float != 0)
640 gravity = val->_float;
643 gravity *= sv_gravity.value * 0.025;
645 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
647 SV_CheckVelocity (tossent);
648 tossent->fields.server->velocity[2] -= gravity;
649 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
650 VectorScale (tossent->fields.server->velocity, 0.05, move);
651 VectorAdd (tossent->fields.server->origin, move, end);
652 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
653 VectorCopy (trace.endpos, tossent->fields.server->origin);
654 tossent->fields.server->velocity[2] -= gravity;
656 if (trace.fraction < 1)
660 VectorCopy(original_origin , tossent->fields.server->origin );
661 VectorCopy(original_velocity , tossent->fields.server->velocity );
662 VectorCopy(original_angles , tossent->fields.server->angles );
663 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
668 static void VM_SV_tracetoss (void)
672 prvm_edict_t *ignore;
674 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
676 prog->xfunction->builtinsprofile += 600;
678 ent = PRVM_G_EDICT(OFS_PARM0);
679 if (ent == prog->edicts)
681 VM_Warning("tracetoss: can not use world entity\n");
684 ignore = PRVM_G_EDICT(OFS_PARM1);
686 trace = SV_Trace_Toss (ent, ignore);
688 VM_SetTraceGlobals(&trace);
691 //============================================================================
693 static int checkpvsbytes;
694 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
696 static int VM_SV_newcheckclient (int check)
702 // cycle to the next one
704 check = bound(1, check, svs.maxclients);
705 if (check == svs.maxclients)
713 prog->xfunction->builtinsprofile++;
715 if (i == svs.maxclients+1)
717 // look up the client's edict
718 ent = PRVM_EDICT_NUM(i);
719 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
720 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
722 // found a valid client (possibly the same one again)
726 // get the PVS for the entity
727 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
729 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
730 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
739 Returns a client (or object that has a client enemy) that would be a
742 If there is more than one valid option, they are cycled each frame
744 If (self.origin + self.viewofs) is not in the PVS of the current target,
745 it is not returned at all.
750 int c_invis, c_notvis;
751 static void VM_SV_checkclient (void)
753 prvm_edict_t *ent, *self;
756 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
758 // find a new check if on a new frame
759 if (sv.time - sv.lastchecktime >= 0.1)
761 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
762 sv.lastchecktime = sv.time;
765 // return check if it might be visible
766 ent = PRVM_EDICT_NUM(sv.lastcheck);
767 if (ent->priv.server->free || ent->fields.server->health <= 0)
769 VM_RETURN_EDICT(prog->edicts);
773 // if current entity can't possibly see the check entity, return 0
774 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
775 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
776 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
779 VM_RETURN_EDICT(prog->edicts);
783 // might be able to see it
785 VM_RETURN_EDICT(ent);
788 //============================================================================
795 Sends text over to the client's execution buffer
797 stuffcmd (clientent, value, ...)
800 static void VM_SV_stuffcmd (void)
804 char string[VM_STRINGTEMP_LENGTH];
806 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
808 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
809 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
811 VM_Warning("Can't stuffcmd to a non-client\n");
815 VM_VarString(1, string, sizeof(string));
818 host_client = svs.clients + entnum-1;
819 Host_ClientCommands ("%s", string);
827 Returns a chain of entities that have origins within a spherical area
829 findradius (origin, radius)
832 static void VM_SV_findradius (void)
834 prvm_edict_t *ent, *chain;
835 vec_t radius, radius2;
836 vec3_t org, eorg, mins, maxs;
839 prvm_edict_t *touchedicts[MAX_EDICTS];
841 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
843 chain = (prvm_edict_t *)prog->edicts;
845 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
846 radius = PRVM_G_FLOAT(OFS_PARM1);
847 radius2 = radius * radius;
849 mins[0] = org[0] - (radius + 1);
850 mins[1] = org[1] - (radius + 1);
851 mins[2] = org[2] - (radius + 1);
852 maxs[0] = org[0] + (radius + 1);
853 maxs[1] = org[1] + (radius + 1);
854 maxs[2] = org[2] + (radius + 1);
855 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
856 if (numtouchedicts > MAX_EDICTS)
858 // this never happens
859 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
860 numtouchedicts = MAX_EDICTS;
862 for (i = 0;i < numtouchedicts;i++)
864 ent = touchedicts[i];
865 prog->xfunction->builtinsprofile++;
866 // Quake did not return non-solid entities but darkplaces does
867 // (note: this is the reason you can't blow up fallen zombies)
868 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
870 // LordHavoc: compare against bounding box rather than center so it
871 // doesn't miss large objects, and use DotProduct instead of Length
872 // for a major speedup
873 VectorSubtract(org, ent->fields.server->origin, eorg);
874 if (sv_gameplayfix_findradiusdistancetobox.integer)
876 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
877 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
878 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
881 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
882 if (DotProduct(eorg, eorg) < radius2)
884 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
889 VM_RETURN_EDICT(chain);
892 static void VM_SV_precache_sound (void)
894 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
895 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
898 static void VM_SV_precache_model (void)
900 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
901 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
902 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
909 float(float yaw, float dist[, settrace]) walkmove
912 static void VM_SV_walkmove (void)
921 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
923 // assume failure if it returns early
924 PRVM_G_FLOAT(OFS_RETURN) = 0;
926 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
927 if (ent == prog->edicts)
929 VM_Warning("walkmove: can not modify world entity\n");
932 if (ent->priv.server->free)
934 VM_Warning("walkmove: can not modify free entity\n");
937 yaw = PRVM_G_FLOAT(OFS_PARM0);
938 dist = PRVM_G_FLOAT(OFS_PARM1);
939 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
941 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
944 yaw = yaw*M_PI*2 / 360;
946 move[0] = cos(yaw)*dist;
947 move[1] = sin(yaw)*dist;
950 // save program state, because SV_movestep may call other progs
951 oldf = prog->xfunction;
952 oldself = prog->globals.server->self;
954 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
957 // restore program state
958 prog->xfunction = oldf;
959 prog->globals.server->self = oldself;
969 static void VM_SV_droptofloor (void)
975 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
977 // assume failure if it returns early
978 PRVM_G_FLOAT(OFS_RETURN) = 0;
980 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
981 if (ent == prog->edicts)
983 VM_Warning("droptofloor: can not modify world entity\n");
986 if (ent->priv.server->free)
988 VM_Warning("droptofloor: can not modify free entity\n");
992 VectorCopy (ent->fields.server->origin, end);
995 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
996 SV_UnstickEntity(ent);
998 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
999 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1002 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]);
1003 VectorAdd(ent->fields.server->origin, offset, org);
1004 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1005 VectorSubtract(trace.endpos, offset, trace.endpos);
1006 if (trace.startsolid)
1008 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]);
1009 SV_UnstickEntity(ent);
1010 SV_LinkEdict (ent, false);
1011 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1012 ent->fields.server->groundentity = 0;
1013 PRVM_G_FLOAT(OFS_RETURN) = 1;
1015 else if (trace.fraction < 1)
1017 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]);
1018 VectorCopy (trace.endpos, ent->fields.server->origin);
1019 SV_UnstickEntity(ent);
1020 SV_LinkEdict (ent, false);
1021 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1022 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1023 PRVM_G_FLOAT(OFS_RETURN) = 1;
1024 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1025 ent->priv.server->suspendedinairflag = true;
1030 if (trace.fraction != 1)
1032 if (trace.fraction < 1)
1033 VectorCopy (trace.endpos, ent->fields.server->origin);
1034 SV_LinkEdict (ent, false);
1035 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1036 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1037 PRVM_G_FLOAT(OFS_RETURN) = 1;
1038 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1039 ent->priv.server->suspendedinairflag = true;
1048 void(float style, string value) lightstyle
1051 static void VM_SV_lightstyle (void)
1058 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1060 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1061 val = PRVM_G_STRING(OFS_PARM1);
1063 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1064 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1067 // change the string in sv
1068 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1070 // send message to all clients on this server
1071 if (sv.state != ss_active)
1074 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1076 if (client->active && client->netconnection)
1078 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1079 MSG_WriteChar (&client->netconnection->message,style);
1080 MSG_WriteString (&client->netconnection->message, val);
1090 static void VM_SV_checkbottom (void)
1092 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1093 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1101 static void VM_SV_pointcontents (void)
1103 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1104 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1111 Pick a vector for the player to shoot along
1112 vector aim(entity, missilespeed)
1115 static void VM_SV_aim (void)
1117 prvm_edict_t *ent, *check, *bestent;
1118 vec3_t start, dir, end, bestdir;
1121 float dist, bestdist;
1124 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1126 // assume failure if it returns early
1127 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1128 // if sv_aim is so high it can't possibly accept anything, skip out early
1129 if (sv_aim.value >= 1)
1132 ent = PRVM_G_EDICT(OFS_PARM0);
1133 if (ent == prog->edicts)
1135 VM_Warning("aim: can not use world entity\n");
1138 if (ent->priv.server->free)
1140 VM_Warning("aim: can not use free entity\n");
1143 speed = PRVM_G_FLOAT(OFS_PARM1);
1145 VectorCopy (ent->fields.server->origin, start);
1148 // try sending a trace straight
1149 VectorCopy (prog->globals.server->v_forward, dir);
1150 VectorMA (start, 2048, dir, end);
1151 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1152 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1153 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1155 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1160 // try all possible entities
1161 VectorCopy (dir, bestdir);
1162 bestdist = sv_aim.value;
1165 check = PRVM_NEXT_EDICT(prog->edicts);
1166 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1168 prog->xfunction->builtinsprofile++;
1169 if (check->fields.server->takedamage != DAMAGE_AIM)
1173 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1174 continue; // don't aim at teammate
1175 for (j=0 ; j<3 ; j++)
1176 end[j] = check->fields.server->origin[j]
1177 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1178 VectorSubtract (end, start, dir);
1179 VectorNormalize (dir);
1180 dist = DotProduct (dir, prog->globals.server->v_forward);
1181 if (dist < bestdist)
1182 continue; // to far to turn
1183 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1184 if (tr.ent == check)
1185 { // can shoot at this one
1193 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1194 dist = DotProduct (dir, prog->globals.server->v_forward);
1195 VectorScale (prog->globals.server->v_forward, dist, end);
1197 VectorNormalize (end);
1198 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1202 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1207 ===============================================================================
1211 ===============================================================================
1214 #define MSG_BROADCAST 0 // unreliable to all
1215 #define MSG_ONE 1 // reliable to one (msg_entity)
1216 #define MSG_ALL 2 // reliable to all
1217 #define MSG_INIT 3 // write to the init string
1218 #define MSG_ENTITY 5
1220 sizebuf_t *WriteDest (void)
1226 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1230 return &sv.datagram;
1233 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1234 entnum = PRVM_NUM_FOR_EDICT(ent);
1235 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1237 VM_Warning ("WriteDest: tried to write to non-client\n");
1238 return &sv.reliable_datagram;
1241 return &svs.clients[entnum-1].netconnection->message;
1244 VM_Warning ("WriteDest: bad destination\n");
1246 return &sv.reliable_datagram;
1252 return sv.writeentitiestoclient_msg;
1258 static void VM_SV_WriteByte (void)
1260 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1261 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1264 static void VM_SV_WriteChar (void)
1266 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1267 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1270 static void VM_SV_WriteShort (void)
1272 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1273 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1276 static void VM_SV_WriteLong (void)
1278 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1279 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1282 static void VM_SV_WriteAngle (void)
1284 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1285 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1288 static void VM_SV_WriteCoord (void)
1290 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1291 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1294 static void VM_SV_WriteString (void)
1296 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1297 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1300 static void VM_SV_WriteUnterminatedString (void)
1302 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1303 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1307 static void VM_SV_WriteEntity (void)
1309 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1310 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1313 // writes a picture as at most size bytes of data
1315 // IMGNAME \0 SIZE(short) IMGDATA
1316 // if failed to read/compress:
1318 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1319 static void VM_SV_WritePicture (void)
1321 const char *imgname;
1325 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1327 imgname = PRVM_G_STRING(OFS_PARM1);
1328 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1332 MSG_WriteString(WriteDest(), imgname);
1333 if(Image_Compress(imgname, size, &buf, &size))
1336 MSG_WriteShort(WriteDest(), size);
1337 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1342 MSG_WriteShort(WriteDest(), 0);
1346 //////////////////////////////////////////////////////////
1348 static void VM_SV_makestatic (void)
1353 // allow 0 parameters due to an id1 qc bug in which this function is used
1354 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1355 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1357 if (prog->argc >= 1)
1358 ent = PRVM_G_EDICT(OFS_PARM0);
1360 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1361 if (ent == prog->edicts)
1363 VM_Warning("makestatic: can not modify world entity\n");
1366 if (ent->priv.server->free)
1368 VM_Warning("makestatic: can not modify free entity\n");
1373 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1378 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1379 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1380 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1382 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1384 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1385 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1386 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1390 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1391 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1392 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1395 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1396 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1397 for (i=0 ; i<3 ; i++)
1399 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1400 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1403 // throw the entity away now
1407 //=============================================================================
1414 static void VM_SV_setspawnparms (void)
1420 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1422 ent = PRVM_G_EDICT(OFS_PARM0);
1423 i = PRVM_NUM_FOR_EDICT(ent);
1424 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1426 Con_Print("tried to setspawnparms on a non-client\n");
1430 // copy spawn parms out of the client_t
1431 client = svs.clients + i-1;
1432 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1433 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1440 Returns a color vector indicating the lighting at the requested point.
1442 (Internal Operation note: actually measures the light beneath the point, just like
1443 the model lighting on the client)
1448 static void VM_SV_getlight (void)
1450 vec3_t ambientcolor, diffusecolor, diffusenormal;
1452 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1453 p = PRVM_G_VECTOR(OFS_PARM0);
1454 VectorClear(ambientcolor);
1455 VectorClear(diffusecolor);
1456 VectorClear(diffusenormal);
1457 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1458 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1459 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1464 unsigned char type; // 1/2/8 or other value if isn't used
1468 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1469 static int vm_customstats_last;
1471 void VM_CustomStats_Clear (void)
1475 Z_Free(vm_customstats);
1476 vm_customstats = NULL;
1477 vm_customstats_last = -1;
1481 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1489 for(i=0; i<vm_customstats_last+1 ;i++)
1491 if(!vm_customstats[i].type)
1493 switch(vm_customstats[i].type)
1495 //string as 16 bytes
1498 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1499 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1500 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1501 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1502 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1504 //float field sent as-is
1506 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1508 //integer value of float field
1510 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1518 // void(float index, float type, .void field) SV_AddStat = #232;
1519 // Set up an auto-sent player stat.
1520 // Client's get thier own fields sent to them. Index may not be less than 32.
1521 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1522 // 1: string (4 stats carrying a total of 16 charactures)
1523 // 2: float (one stat, float converted to an integer for transportation)
1524 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1525 static void VM_SV_AddStat (void)
1530 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1534 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1537 VM_Warning("PF_SV_AddStat: not enough memory\n");
1541 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1542 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1543 off = PRVM_G_INT (OFS_PARM2);
1548 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1551 if(i >= (MAX_CL_STATS-32))
1553 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1556 if(i > (MAX_CL_STATS-32-4) && type == 1)
1558 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1561 vm_customstats[i].type = type;
1562 vm_customstats[i].fieldoffset = off;
1563 if(vm_customstats_last < i)
1564 vm_customstats_last = i;
1571 copies data from one entity to another
1573 copyentity(src, dst)
1576 static void VM_SV_copyentity (void)
1578 prvm_edict_t *in, *out;
1579 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1580 in = PRVM_G_EDICT(OFS_PARM0);
1581 if (in == prog->edicts)
1583 VM_Warning("copyentity: can not read world entity\n");
1586 if (in->priv.server->free)
1588 VM_Warning("copyentity: can not read free entity\n");
1591 out = PRVM_G_EDICT(OFS_PARM1);
1592 if (out == prog->edicts)
1594 VM_Warning("copyentity: can not modify world entity\n");
1597 if (out->priv.server->free)
1599 VM_Warning("copyentity: can not modify free entity\n");
1602 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1603 SV_LinkEdict(out, false);
1611 sets the color of a client and broadcasts the update to all connected clients
1613 setcolor(clientent, value)
1616 static void VM_SV_setcolor (void)
1622 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1623 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1624 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1626 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1628 Con_Print("tried to setcolor a non-client\n");
1632 client = svs.clients + entnum-1;
1635 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1637 client->edict->fields.server->team = (i & 15) + 1;
1640 if (client->old_colors != client->colors)
1642 client->old_colors = client->colors;
1643 // send notification to all clients
1644 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1645 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1646 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1654 effect(origin, modelname, startframe, framecount, framerate)
1657 static void VM_SV_effect (void)
1661 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1662 s = PRVM_G_STRING(OFS_PARM1);
1665 VM_Warning("effect: no model specified\n");
1669 i = SV_ModelIndex(s, 1);
1672 VM_Warning("effect: model not precached\n");
1676 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1678 VM_Warning("effect: framecount < 1\n");
1682 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1684 VM_Warning("effect: framerate < 1\n");
1688 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));
1691 static void VM_SV_te_blood (void)
1693 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1694 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1696 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1697 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1699 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1700 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1701 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1703 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1704 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1705 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1707 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1708 SV_FlushBroadcastMessages();
1711 static void VM_SV_te_bloodshower (void)
1713 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1714 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1716 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1717 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1727 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1729 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1730 SV_FlushBroadcastMessages();
1733 static void VM_SV_te_explosionrgb (void)
1735 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1736 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1737 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1740 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1741 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1743 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1744 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1745 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1746 SV_FlushBroadcastMessages();
1749 static void VM_SV_te_particlecube (void)
1751 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1752 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1754 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1755 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1763 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1769 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1771 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1772 // gravity true/false
1773 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1775 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1776 SV_FlushBroadcastMessages();
1779 static void VM_SV_te_particlerain (void)
1781 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1782 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1784 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1785 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1792 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1793 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1795 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1796 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1797 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1799 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1801 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1802 SV_FlushBroadcastMessages();
1805 static void VM_SV_te_particlesnow (void)
1807 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1808 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1810 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1811 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1822 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1823 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1825 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1827 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1828 SV_FlushBroadcastMessages();
1831 static void VM_SV_te_spark (void)
1833 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1834 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1836 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1837 MSG_WriteByte(&sv.datagram, TE_SPARK);
1839 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1840 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1841 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1843 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1844 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1845 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1847 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1848 SV_FlushBroadcastMessages();
1851 static void VM_SV_te_gunshotquad (void)
1853 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1854 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1855 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1860 SV_FlushBroadcastMessages();
1863 static void VM_SV_te_spikequad (void)
1865 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
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);
1872 SV_FlushBroadcastMessages();
1875 static void VM_SV_te_superspikequad (void)
1877 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1878 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1879 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1882 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1883 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1884 SV_FlushBroadcastMessages();
1887 static void VM_SV_te_explosionquad (void)
1889 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1890 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1891 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1895 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1896 SV_FlushBroadcastMessages();
1899 static void VM_SV_te_smallflash (void)
1901 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1902 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1903 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1908 SV_FlushBroadcastMessages();
1911 static void VM_SV_te_customflash (void)
1913 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1914 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1916 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1917 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1923 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1925 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1927 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1928 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1929 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1930 SV_FlushBroadcastMessages();
1933 static void VM_SV_te_gunshot (void)
1935 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1936 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1937 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
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);
1942 SV_FlushBroadcastMessages();
1945 static void VM_SV_te_spike (void)
1947 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1948 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1949 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1954 SV_FlushBroadcastMessages();
1957 static void VM_SV_te_superspike (void)
1959 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1960 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1961 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1964 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1965 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1966 SV_FlushBroadcastMessages();
1969 static void VM_SV_te_explosion (void)
1971 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1972 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1973 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1978 SV_FlushBroadcastMessages();
1981 static void VM_SV_te_tarexplosion (void)
1983 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1984 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1985 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1990 SV_FlushBroadcastMessages();
1993 static void VM_SV_te_wizspike (void)
1995 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1996 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1997 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
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);
2002 SV_FlushBroadcastMessages();
2005 static void VM_SV_te_knightspike (void)
2007 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2008 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2009 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2014 SV_FlushBroadcastMessages();
2017 static void VM_SV_te_lavasplash (void)
2019 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2020 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2021 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2023 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2024 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2025 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2026 SV_FlushBroadcastMessages();
2029 static void VM_SV_te_teleport (void)
2031 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2032 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2033 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2035 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2036 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2037 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2038 SV_FlushBroadcastMessages();
2041 static void VM_SV_te_explosion2 (void)
2043 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2044 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2045 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2047 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2048 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2049 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2051 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2052 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2053 SV_FlushBroadcastMessages();
2056 static void VM_SV_te_lightning1 (void)
2058 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2059 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2060 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2062 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2065 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2069 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2070 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2071 SV_FlushBroadcastMessages();
2074 static void VM_SV_te_lightning2 (void)
2076 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2077 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2078 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
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);
2089 SV_FlushBroadcastMessages();
2092 static void VM_SV_te_lightning3 (void)
2094 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2095 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2096 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2098 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2101 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2102 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2104 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2105 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2106 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2107 SV_FlushBroadcastMessages();
2110 static void VM_SV_te_beam (void)
2112 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2113 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2114 MSG_WriteByte(&sv.datagram, TE_BEAM);
2116 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2118 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2119 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2120 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2122 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2123 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2124 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2125 SV_FlushBroadcastMessages();
2128 static void VM_SV_te_plasmaburn (void)
2130 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2131 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2132 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2133 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2134 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2135 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2136 SV_FlushBroadcastMessages();
2139 static void VM_SV_te_flamejet (void)
2141 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2142 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2143 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2145 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2146 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2147 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2149 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2150 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2151 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2153 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2154 SV_FlushBroadcastMessages();
2157 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2160 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2162 bestdist = 1000000000;
2164 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2166 // clip original point to each triangle of the surface and find the
2167 // triangle that is closest
2168 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2169 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2170 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2171 TriangleNormal(v[0], v[1], v[2], facenormal);
2172 VectorNormalize(facenormal);
2173 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2174 VectorMA(p, offsetdist, facenormal, temp);
2175 for (j = 0, k = 2;j < 3;k = j, j++)
2177 VectorSubtract(v[k], v[j], edgenormal);
2178 CrossProduct(edgenormal, facenormal, sidenormal);
2179 VectorNormalize(sidenormal);
2180 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2182 VectorMA(temp, offsetdist, sidenormal, temp);
2184 dist = VectorDistance2(temp, p);
2185 if (bestdist > dist)
2188 VectorCopy(temp, out);
2193 static dp_model_t *getmodel(prvm_edict_t *ed)
2196 if (!ed || ed->priv.server->free)
2198 modelindex = (int)ed->fields.server->modelindex;
2199 if (modelindex < 1 || modelindex >= MAX_MODELS)
2201 return sv.models[modelindex];
2204 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2206 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2208 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2212 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2213 static void VM_SV_getsurfacenumpoints(void)
2216 msurface_t *surface;
2217 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2218 // return 0 if no such surface
2219 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2221 PRVM_G_FLOAT(OFS_RETURN) = 0;
2225 // note: this (incorrectly) assumes it is a simple polygon
2226 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2228 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2229 static void VM_SV_getsurfacepoint(void)
2233 msurface_t *surface;
2235 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2236 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2237 ed = PRVM_G_EDICT(OFS_PARM0);
2238 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2240 // note: this (incorrectly) assumes it is a simple polygon
2241 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2242 if (pointnum < 0 || pointnum >= surface->num_vertices)
2244 // FIXME: implement rotation/scaling
2245 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2247 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2248 // float SPA_POSITION = 0;
2249 // float SPA_S_AXIS = 1;
2250 // float SPA_T_AXIS = 2;
2251 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2252 // float SPA_TEXCOORDS0 = 4;
2253 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2254 // float SPA_LIGHTMAP0_COLOR = 6;
2255 static void VM_SV_getsurfacepointattribute(void)
2259 msurface_t *surface;
2263 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2264 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2265 ed = PRVM_G_EDICT(OFS_PARM0);
2266 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2268 // note: this (incorrectly) assumes it is a simple polygon
2269 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2270 if (pointnum < 0 || pointnum >= surface->num_vertices)
2272 // FIXME: implement rotation/scaling
2273 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2275 switch( attributetype ) {
2276 // float SPA_POSITION = 0;
2278 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2280 // float SPA_S_AXIS = 1;
2282 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2284 // float SPA_T_AXIS = 2;
2286 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2288 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2290 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2292 // float SPA_TEXCOORDS0 = 4;
2294 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2295 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2296 ret[0] = texcoord[0];
2297 ret[1] = texcoord[1];
2301 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2303 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2304 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2305 ret[0] = texcoord[0];
2306 ret[1] = texcoord[1];
2310 // float SPA_LIGHTMAP0_COLOR = 6;
2312 // ignore alpha for now..
2313 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2316 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2320 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2321 static void VM_SV_getsurfacenormal(void)
2324 msurface_t *surface;
2326 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2327 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2328 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2330 // FIXME: implement rotation/scaling
2331 // note: this (incorrectly) assumes it is a simple polygon
2332 // note: this only returns the first triangle, so it doesn't work very
2333 // well for curved surfaces or arbitrary meshes
2334 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);
2335 VectorNormalize(normal);
2336 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2338 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2339 static void VM_SV_getsurfacetexture(void)
2342 msurface_t *surface;
2343 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2344 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2345 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2347 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2349 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2350 static void VM_SV_getsurfacenearpoint(void)
2352 int surfacenum, best;
2354 vec_t dist, bestdist;
2357 msurface_t *surface;
2359 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2360 PRVM_G_FLOAT(OFS_RETURN) = -1;
2361 ed = PRVM_G_EDICT(OFS_PARM0);
2362 point = PRVM_G_VECTOR(OFS_PARM1);
2364 if (!ed || ed->priv.server->free)
2366 model = getmodel(ed);
2367 if (!model || !model->num_surfaces)
2370 // FIXME: implement rotation/scaling
2371 VectorSubtract(point, ed->fields.server->origin, p);
2373 bestdist = 1000000000;
2374 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2376 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2377 // first see if the nearest point on the surface's box is closer than the previous match
2378 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2379 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2380 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2381 dist = VectorLength2(clipped);
2382 if (dist < bestdist)
2384 // it is, check the nearest point on the actual geometry
2385 clippointtosurface(model, surface, p, clipped);
2386 VectorSubtract(clipped, p, clipped);
2387 dist += VectorLength2(clipped);
2388 if (dist < bestdist)
2390 // that's closer too, store it as the best match
2396 PRVM_G_FLOAT(OFS_RETURN) = best;
2398 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2399 static void VM_SV_getsurfaceclippedpoint(void)
2403 msurface_t *surface;
2405 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2406 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2407 ed = PRVM_G_EDICT(OFS_PARM0);
2408 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2410 // FIXME: implement rotation/scaling
2411 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2412 clippointtosurface(model, surface, p, out);
2413 // FIXME: implement rotation/scaling
2414 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2417 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2418 //this function originally written by KrimZon, made shorter by LordHavoc
2419 static void VM_SV_clientcommand (void)
2421 client_t *temp_client;
2423 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2425 //find client for this entity
2426 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2427 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2429 Con_Print("PF_clientcommand: entity is not a client\n");
2433 temp_client = host_client;
2434 host_client = svs.clients + i;
2435 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2436 host_client = temp_client;
2439 //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)
2440 static void VM_SV_setattachment (void)
2442 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2443 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2444 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2448 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2450 if (e == prog->edicts)
2452 VM_Warning("setattachment: can not modify world entity\n");
2455 if (e->priv.server->free)
2457 VM_Warning("setattachment: can not modify free entity\n");
2461 if (tagentity == NULL)
2462 tagentity = prog->edicts;
2464 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2466 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2468 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2471 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2473 modelindex = (int)tagentity->fields.server->modelindex;
2474 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2476 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2478 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);
2481 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));
2485 /////////////////////////////////////////
2486 // DP_MD3_TAGINFO extension coded by VorteX
2488 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2493 i = (int)e->fields.server->modelindex;
2494 if (i < 1 || i >= MAX_MODELS)
2496 model = sv.models[i];
2498 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2501 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2510 Matrix4x4_CreateIdentity(tag_localmatrix);
2513 && (modelindex = (int)e->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2514 && (model = sv.models[(int)e->fields.server->modelindex])
2515 && model->animscenes)
2517 frame = (int)e->fields.server->frame;
2518 if (frame < 0 || frame >= model->numframes)
2521 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, model->animscenes[frame].firstframe, tagindex - 1, parentindex, tagname, tag_localmatrix);
2532 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2534 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2538 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);
2540 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);
2543 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2549 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2550 && (model = sv.models[(int)ent->fields.server->modelindex])
2551 && model->animscenes)
2553 // if model has wrong frame, engine automatically switches to model first frame
2554 frame = (int)ent->fields.server->frame;
2555 if (frame < 0 || frame >= model->numframes)
2557 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2559 *out = identitymatrix;
2563 // Warnings/errors code:
2564 // 0 - normal (everything all-right)
2567 // 3 - null or non-precached model
2568 // 4 - no tags with requested index
2569 // 5 - runaway loop at attachment chain
2570 extern cvar_t cl_bob;
2571 extern cvar_t cl_bobcycle;
2572 extern cvar_t cl_bobup;
2573 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2577 int modelindex, attachloop;
2578 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2581 *out = identitymatrix; // warnings and errors return identical matrix
2583 if (ent == prog->edicts)
2585 if (ent->priv.server->free)
2588 modelindex = (int)ent->fields.server->modelindex;
2589 if (modelindex <= 0 || modelindex > MAX_MODELS)
2592 model = sv.models[modelindex];
2594 tagmatrix = identitymatrix;
2595 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2599 if (attachloop >= 256) // prevent runaway looping
2601 // apply transformation by child's tagindex on parent entity and then
2602 // by parent entity itself
2603 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2604 if (ret && attachloop == 0)
2606 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2607 SV_GetEntityMatrix(ent, &entitymatrix, false);
2608 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2609 // next iteration we process the parent entity
2610 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2612 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2613 ent = PRVM_EDICT_NUM(val->edict);
2620 // RENDER_VIEWMODEL magic
2621 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2623 Matrix4x4_Copy(&tagmatrix, out);
2624 ent = PRVM_EDICT_NUM(val->edict);
2626 SV_GetEntityMatrix(ent, &entitymatrix, true);
2627 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2630 // Cl_bob, ported from rendering code
2631 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2634 // LordHavoc: this code is *weird*, but not replacable (I think it
2635 // should be done in QC on the server, but oh well, quake is quake)
2636 // LordHavoc: figured out bobup: the time at which the sin is at 180
2637 // degrees (which allows lengthening or squishing the peak or valley)
2638 cycle = sv.time/cl_bobcycle.value;
2639 cycle -= (int)cycle;
2640 if (cycle < cl_bobup.value)
2641 cycle = sin(M_PI * cycle / cl_bobup.value);
2643 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2644 // bob is proportional to velocity in the xy plane
2645 // (don't count Z, or jumping messes it up)
2646 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;
2647 bob = bob*0.3 + bob*0.7*cycle;
2648 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2655 //float(entity ent, string tagname) gettagindex;
2657 static void VM_SV_gettagindex (void)
2660 const char *tag_name;
2661 int modelindex, tag_index;
2663 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2665 ent = PRVM_G_EDICT(OFS_PARM0);
2666 tag_name = PRVM_G_STRING(OFS_PARM1);
2668 if (ent == prog->edicts)
2670 VM_Warning("gettagindex: can't affect world entity\n");
2673 if (ent->priv.server->free)
2675 VM_Warning("gettagindex: can't affect free entity\n");
2679 modelindex = (int)ent->fields.server->modelindex;
2681 if (modelindex <= 0 || modelindex > MAX_MODELS)
2682 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2685 tag_index = SV_GetTagIndex(ent, tag_name);
2687 if(developer.integer >= 100)
2688 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2690 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2693 //vector(entity ent, float tagindex) gettaginfo;
2694 static void VM_SV_gettaginfo (void)
2698 matrix4x4_t tag_matrix;
2699 matrix4x4_t tag_localmatrix;
2701 const char *tagname;
2704 vec3_t fo, ri, up, trans;
2706 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2708 e = PRVM_G_EDICT(OFS_PARM0);
2709 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2711 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2712 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2713 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2714 Matrix4x4_ToVectors(&tag_localmatrix, fo, ri, up, trans);
2716 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2717 val->_float = parentindex;
2718 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2719 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2720 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2721 VectorCopy(trans, val->vector);
2722 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2723 VectorCopy(fo, val->vector);
2724 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2725 VectorCopy(ri, val->vector);
2726 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2727 VectorCopy(up, val->vector);
2732 VM_Warning("gettagindex: can't affect world entity\n");
2735 VM_Warning("gettagindex: can't affect free entity\n");
2738 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2741 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2744 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2749 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2750 static void VM_SV_dropclient (void)
2753 client_t *oldhostclient;
2754 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2755 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2756 if (clientnum < 0 || clientnum >= svs.maxclients)
2758 VM_Warning("dropclient: not a client\n");
2761 if (!svs.clients[clientnum].active)
2763 VM_Warning("dropclient: that client slot is not connected\n");
2766 oldhostclient = host_client;
2767 host_client = svs.clients + clientnum;
2768 SV_DropClient(false);
2769 host_client = oldhostclient;
2772 //entity() spawnclient (DP_SV_BOTCLIENT)
2773 static void VM_SV_spawnclient (void)
2777 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2778 prog->xfunction->builtinsprofile += 2;
2780 for (i = 0;i < svs.maxclients;i++)
2782 if (!svs.clients[i].active)
2784 prog->xfunction->builtinsprofile += 100;
2785 SV_ConnectClient (i, NULL);
2786 // this has to be set or else ClientDisconnect won't be called
2787 // we assume the qc will call ClientConnect...
2788 svs.clients[i].clientconnectcalled = true;
2789 ed = PRVM_EDICT_NUM(i + 1);
2793 VM_RETURN_EDICT(ed);
2796 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2797 static void VM_SV_clienttype (void)
2800 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2801 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2802 if (clientnum < 0 || clientnum >= svs.maxclients)
2803 PRVM_G_FLOAT(OFS_RETURN) = 3;
2804 else if (!svs.clients[clientnum].active)
2805 PRVM_G_FLOAT(OFS_RETURN) = 0;
2806 else if (svs.clients[clientnum].netconnection)
2807 PRVM_G_FLOAT(OFS_RETURN) = 1;
2809 PRVM_G_FLOAT(OFS_RETURN) = 2;
2816 string(string key) serverkey
2819 void VM_SV_serverkey(void)
2821 char string[VM_STRINGTEMP_LENGTH];
2822 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2823 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2824 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2827 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2828 static void VM_SV_setmodelindex (void)
2833 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2835 e = PRVM_G_EDICT(OFS_PARM0);
2836 if (e == prog->edicts)
2838 VM_Warning("setmodelindex: can not modify world entity\n");
2841 if (e->priv.server->free)
2843 VM_Warning("setmodelindex: can not modify free entity\n");
2846 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2847 if (i <= 0 || i > MAX_MODELS)
2849 VM_Warning("setmodelindex: invalid modelindex\n");
2852 if (!sv.model_precache[i][0])
2854 VM_Warning("setmodelindex: model not precached\n");
2858 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2859 e->fields.server->modelindex = i;
2865 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2866 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2868 SetMinMaxSize (e, quakemins, quakemaxs, true);
2871 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2874 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2875 static void VM_SV_modelnameforindex (void)
2878 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2880 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2882 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2883 if (i <= 0 || i > MAX_MODELS)
2885 VM_Warning("modelnameforindex: invalid modelindex\n");
2888 if (!sv.model_precache[i][0])
2890 VM_Warning("modelnameforindex: model not precached\n");
2894 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2897 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2898 static void VM_SV_particleeffectnum (void)
2901 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2902 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2905 PRVM_G_FLOAT(OFS_RETURN) = i;
2908 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2909 static void VM_SV_trailparticles (void)
2911 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2913 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2916 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2917 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2918 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2919 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2920 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2921 SV_FlushBroadcastMessages();
2924 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2925 static void VM_SV_pointparticles (void)
2927 int effectnum, count;
2929 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2931 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2934 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2935 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2936 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2937 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2938 if (count == 1 && !VectorLength2(vel))
2941 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2942 MSG_WriteShort(&sv.datagram, effectnum);
2943 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2947 // 1+2+12+12+2=29 bytes
2948 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2949 MSG_WriteShort(&sv.datagram, effectnum);
2950 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2951 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2952 MSG_WriteShort(&sv.datagram, count);
2955 SV_FlushBroadcastMessages();
2958 //PF_setpause, // void(float pause) setpause = #531;
2959 static void VM_SV_setpause(void) {
2961 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2962 if (pauseValue != 0) { //pause the game
2964 sv.pausedstart = Sys_DoubleTime();
2965 } else { //disable pause, in case it was enabled
2966 if (sv.paused != 0) {
2971 // send notification to all clients
2972 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2973 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2976 prvm_builtin_t vm_sv_builtins[] = {
2977 NULL, // #0 NULL function (not callable) (QUAKE)
2978 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2979 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2980 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2981 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2982 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2983 VM_break, // #6 void() break (QUAKE)
2984 VM_random, // #7 float() random (QUAKE)
2985 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2986 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2987 VM_error, // #10 void(string e) error (QUAKE)
2988 VM_objerror, // #11 void(string e) objerror (QUAKE)
2989 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2990 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2991 VM_spawn, // #14 entity() spawn (QUAKE)
2992 VM_remove, // #15 void(entity e) remove (QUAKE)
2993 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2994 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2995 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2996 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2997 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2998 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2999 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3000 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3001 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3002 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3003 VM_ftos, // #26 string(float f) ftos (QUAKE)
3004 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3005 VM_coredump, // #28 void() coredump (QUAKE)
3006 VM_traceon, // #29 void() traceon (QUAKE)
3007 VM_traceoff, // #30 void() traceoff (QUAKE)
3008 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3009 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3010 NULL, // #33 (QUAKE)
3011 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3012 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3013 VM_rint, // #36 float(float v) rint (QUAKE)
3014 VM_floor, // #37 float(float v) floor (QUAKE)
3015 VM_ceil, // #38 float(float v) ceil (QUAKE)
3016 NULL, // #39 (QUAKE)
3017 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3018 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3019 NULL, // #42 (QUAKE)
3020 VM_fabs, // #43 float(float f) fabs (QUAKE)
3021 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3022 VM_cvar, // #45 float(string s) cvar (QUAKE)
3023 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3024 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3025 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3026 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3027 NULL, // #50 (QUAKE)
3028 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3029 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3030 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3031 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3032 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3033 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3034 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3035 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3036 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3037 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3038 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3039 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3040 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3041 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3042 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3043 NULL, // #66 (QUAKE)
3044 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3045 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3046 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3047 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3048 NULL, // #71 (QUAKE)
3049 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3050 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3051 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3052 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3053 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3054 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3055 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3056 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3057 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3058 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3059 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3060 NULL, // #83 (QUAKE)
3061 NULL, // #84 (QUAKE)
3062 NULL, // #85 (QUAKE)
3063 NULL, // #86 (QUAKE)
3064 NULL, // #87 (QUAKE)
3065 NULL, // #88 (QUAKE)
3066 NULL, // #89 (QUAKE)
3067 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3068 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3069 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3070 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3071 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3072 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3073 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3074 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3075 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3076 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3077 // FrikaC and Telejano range #100-#199
3088 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3089 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3090 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3091 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3092 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3093 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3094 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3095 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3096 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3097 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3178 // FTEQW range #200-#299
3197 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3200 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3201 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3202 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3203 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3204 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3205 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3206 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3207 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3208 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3209 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3211 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3279 // CSQC range #300-#399
3280 NULL, // #300 void() clearscene (EXT_CSQC)
3281 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3282 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3283 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3284 NULL, // #304 void() renderscene (EXT_CSQC)
3285 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3286 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3287 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3288 NULL, // #308 void() R_EndPolygon
3290 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3291 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3295 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3296 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3297 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3298 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3299 NULL, // #319 void(string name) freepic (EXT_CSQC)
3300 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3301 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3302 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3303 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3304 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3305 NULL, // #325 void(void) drawresetcliparea
3310 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3311 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3312 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3313 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3314 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3315 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3316 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3317 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3318 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3319 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3320 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3321 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3322 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3323 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3324 NULL, // #344 vector() getmousepos (EXT_CSQC)
3325 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3326 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3327 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3328 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3329 NULL, // #349 float() isdemo (EXT_CSQC)
3330 VM_isserver, // #350 float() isserver (EXT_CSQC)
3331 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3332 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3333 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3334 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3340 NULL, // #360 float() readbyte (EXT_CSQC)
3341 NULL, // #361 float() readchar (EXT_CSQC)
3342 NULL, // #362 float() readshort (EXT_CSQC)
3343 NULL, // #363 float() readlong (EXT_CSQC)
3344 NULL, // #364 float() readcoord (EXT_CSQC)
3345 NULL, // #365 float() readangle (EXT_CSQC)
3346 NULL, // #366 string() readstring (EXT_CSQC)
3347 NULL, // #367 float() readfloat (EXT_CSQC)
3380 // LordHavoc's range #400-#499
3381 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3382 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3383 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3384 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3385 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3386 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3387 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3388 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3389 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)
3390 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3391 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3392 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3393 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3394 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3395 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3396 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3397 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3398 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3399 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3400 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3401 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3402 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3403 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3404 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3405 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3406 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3407 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3408 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3409 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3410 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3411 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3412 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3413 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3414 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3415 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3416 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3417 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3418 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3419 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3420 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3421 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3422 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3423 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3424 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3425 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3426 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3427 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3428 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3429 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3430 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3431 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3432 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3433 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3434 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3435 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3436 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3437 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3438 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3440 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3441 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3442 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3443 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3444 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3445 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3446 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3447 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3448 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3449 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3450 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3452 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3453 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3454 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3455 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3456 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3457 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3458 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3459 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3460 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3461 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3462 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3463 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3464 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3465 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3466 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3467 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3475 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3476 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3477 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3478 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3479 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3480 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3481 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3482 VM_SV_WritePicture, // #501
3484 VM_whichpack, // #503 string(string) whichpack = #503;
3491 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3492 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3493 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3494 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3495 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3496 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3497 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3498 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3499 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3512 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3516 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3518 void VM_SV_Cmd_Init(void)
3523 void VM_SV_Cmd_Reset(void)
3525 if(prog->funcoffsets.SV_Shutdown)
3527 func_t s = prog->funcoffsets.SV_Shutdown;
3528 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3529 PRVM_ExecuteProgram(s,"SV_Shutdown() required");