3 #include "cl_collision.h"
6 //============================================================================
8 //[515]: unsolved PROBLEMS
9 //- finish player physics code (cs_runplayerphysics)
11 //- RF_DEPTHHACK is not like it should be
12 //- add builtin that sets cl.viewangles instead of reading "input_angles" global
13 //- finish lines support for R_Polygon***
14 //- insert selecttraceline into traceline somehow
16 //4 feature darkplaces csqc: add builtin to clientside qc for reading triangles of model meshes (useful to orient a ui along a triangle of a model mesh)
17 //4 feature darkplaces csqc: add builtins to clientside qc for gl calls
19 sfx_t *S_FindName(const char *name);
20 void PF_registercvar (void);
21 int Sbar_GetPlayer (int index);
22 void Sbar_SortFrags (void);
23 void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
24 void CSQC_RelinkAllEntities (int drawmask);
25 void CSQC_RelinkCSQCEntities (void);
26 char *Key_GetBind (int key);
27 model_t *CSQC_GetModelByIndex(int modelindex);
28 model_t *CSQC_GetModelFromEntity(prvm_edict_t *ed);
29 void CL_LinkEdict(prvm_edict_t *ed);
36 // #1 void(vector ang) makevectors
37 void VM_CL_makevectors (void)
39 VM_SAFEPARMCOUNT(1, VM_CL_makevectors);
40 AngleVectors (PRVM_G_VECTOR(OFS_PARM0), prog->globals.client->v_forward, prog->globals.client->v_right, prog->globals.client->v_up);
43 // #2 void(entity e, vector o) setorigin
44 void VM_CL_setorigin (void)
49 e = PRVM_G_EDICT(OFS_PARM0);
50 if (e == prog->edicts)
52 VM_Warning("setorigin: can not modify world entity\n");
55 if (e->priv.required->free)
57 VM_Warning("setorigin: can not modify free entity\n");
60 org = PRVM_G_VECTOR(OFS_PARM1);
61 VectorCopy (org, e->fields.client->origin);
65 // #3 void(entity e, string m) setmodel
66 void VM_CL_setmodel (void)
73 VM_SAFEPARMCOUNT(2, VM_CL_setmodel);
75 e = PRVM_G_EDICT(OFS_PARM0);
76 m = PRVM_G_STRING(OFS_PARM1);
77 for (i = 0;i < MAX_MODELS && cl.csqc_model_precache[i];i++)
79 if (!strcmp(cl.csqc_model_precache[i]->name, m))
81 e->fields.client->model = PRVM_SetEngineString(cl.csqc_model_precache[i]->name);
82 e->fields.client->modelindex = -(i+1);
87 for (i = 0;i < MAX_MODELS;i++)
89 mod = cl.model_precache[i];
90 if (mod && !strcmp(mod->name, m))
92 e->fields.client->model = PRVM_SetEngineString(mod->name);
93 e->fields.client->modelindex = i;
98 e->fields.client->modelindex = 0;
99 e->fields.client->model = 0;
102 // #4 void(entity e, vector min, vector max) setsize
103 void VM_CL_setsize (void)
107 VM_SAFEPARMCOUNT(3, VM_CL_setsize);
109 e = PRVM_G_EDICT(OFS_PARM0);
110 if (e == prog->edicts)
112 VM_Warning("setsize: can not modify world entity\n");
115 if (e->priv.server->free)
117 VM_Warning("setsize: can not modify free entity\n");
120 min = PRVM_G_VECTOR(OFS_PARM1);
121 max = PRVM_G_VECTOR(OFS_PARM2);
123 VectorCopy (min, e->fields.client->mins);
124 VectorCopy (max, e->fields.client->maxs);
125 VectorSubtract (max, min, e->fields.client->size);
130 // #8 void(entity e, float chan, string samp) sound
131 void VM_CL_sound (void)
135 prvm_edict_t *entity;
139 VM_SAFEPARMCOUNT(5, VM_CL_sound);
141 entity = PRVM_G_EDICT(OFS_PARM0);
142 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
143 sample = PRVM_G_STRING(OFS_PARM2);
144 volume = (int)(PRVM_G_FLOAT(OFS_PARM3)*255.0f);
145 attenuation = PRVM_G_FLOAT(OFS_PARM4);
147 if (volume < 0 || volume > 255)
149 VM_Warning("VM_CL_sound: volume must be in range 0-1\n");
153 if (attenuation < 0 || attenuation > 4)
155 VM_Warning("VM_CL_sound: attenuation must be in range 0-4\n");
159 if (channel < 0 || channel > 7)
161 VM_Warning("VM_CL_sound: channel must be in range 0-7\n");
165 S_StartSound(32768 + PRVM_NUM_FOR_EDICT(entity), channel, S_FindName(sample), entity->fields.client->origin, volume, attenuation);
168 // #14 entity() spawn
169 void VM_CL_spawn (void)
172 ed = PRVM_ED_Alloc();
173 ed->fields.client->entnum = PRVM_NUM_FOR_EDICT(ed); //[515]: not needed any more ?
177 // #16 float(vector v1, vector v2, float tryents) traceline
178 void VM_CL_traceline (void)
184 v1 = PRVM_G_VECTOR(OFS_PARM0);
185 v2 = PRVM_G_VECTOR(OFS_PARM1);
187 trace = CL_TraceBox(v1, vec3_origin, vec3_origin, v2, 1, &ent, 1, false);
189 prog->globals.client->trace_allsolid = trace.allsolid;
190 prog->globals.client->trace_startsolid = trace.startsolid;
191 prog->globals.client->trace_fraction = trace.fraction;
192 prog->globals.client->trace_inwater = trace.inwater;
193 prog->globals.client->trace_inopen = trace.inopen;
194 VectorCopy (trace.endpos, prog->globals.client->trace_endpos);
195 VectorCopy (trace.plane.normal, prog->globals.client->trace_plane_normal);
196 prog->globals.client->trace_plane_dist = trace.plane.dist;
198 prog->globals.client->trace_ent = ent;
200 prog->globals.client->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
203 // #19 void(string s) precache_sound
204 void VM_CL_precache_sound (void)
206 VM_SAFEPARMCOUNT(1, VM_CL_precache_sound);
207 S_PrecacheSound(PRVM_G_STRING(OFS_PARM0), true, false);
210 // #20 void(string s) precache_model
211 void VM_CL_precache_model (void)
217 VM_SAFEPARMCOUNT(1, VM_CL_precache_model);
219 name = PRVM_G_STRING(OFS_PARM0);
220 for (i = 1;i < MAX_MODELS && cl.csqc_model_precache[i];i++)
222 if(!strcmp(cl.csqc_model_precache[i]->name, name))
224 PRVM_G_FLOAT(OFS_RETURN) = -(i+1);
228 PRVM_G_FLOAT(OFS_RETURN) = 0;
229 m = Mod_ForName(name, false, false, false);
232 for (i = 1;i < MAX_MODELS;i++)
234 if (!cl.csqc_model_precache[i])
236 cl.csqc_model_precache[i] = (model_t*)m;
237 PRVM_G_FLOAT(OFS_RETURN) = -(i+1);
241 VM_Warning("VM_CL_precache_model: no free models\n");
244 VM_Warning("VM_CL_precache_model: model \"%s\" not found\n", name);
247 int CSQC_EntitiesInBox (vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list)
252 ent = PRVM_NEXT_EDICT(prog->edicts);
253 for(k=0,i=1; i<prog->num_edicts ;i++, ent = PRVM_NEXT_EDICT(ent))
255 if (ent->priv.required->free)
257 // VectorAdd(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->absmin);
258 // VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, ent->fields.client->absmax);
259 if(BoxesOverlap(mins, maxs, ent->fields.client->absmin, ent->fields.client->absmax))
265 // #22 entity(vector org, float rad) findradius
266 void VM_CL_findradius (void)
268 prvm_edict_t *ent, *chain;
269 vec_t radius, radius2;
270 vec3_t org, eorg, mins, maxs;
271 int i, numtouchedicts;
272 prvm_edict_t *touchedicts[MAX_EDICTS];
274 chain = (prvm_edict_t *)prog->edicts;
276 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
277 radius = PRVM_G_FLOAT(OFS_PARM1);
278 radius2 = radius * radius;
280 mins[0] = org[0] - (radius + 1);
281 mins[1] = org[1] - (radius + 1);
282 mins[2] = org[2] - (radius + 1);
283 maxs[0] = org[0] + (radius + 1);
284 maxs[1] = org[1] + (radius + 1);
285 maxs[2] = org[2] + (radius + 1);
286 numtouchedicts = CSQC_EntitiesInBox(mins, maxs, MAX_EDICTS, touchedicts);
287 if (numtouchedicts > MAX_EDICTS)
289 // this never happens //[515]: for what then ?
290 Con_Printf("CSQC_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
291 numtouchedicts = MAX_EDICTS;
293 for (i = 0;i < numtouchedicts;i++)
295 ent = touchedicts[i];
296 // Quake did not return non-solid entities but darkplaces does
297 // (note: this is the reason you can't blow up fallen zombies)
298 if (ent->fields.client->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
300 // LordHavoc: compare against bounding box rather than center so it
301 // doesn't miss large objects, and use DotProduct instead of Length
302 // for a major speedup
303 VectorSubtract(org, ent->fields.client->origin, eorg);
304 if (sv_gameplayfix_findradiusdistancetobox.integer)
306 eorg[0] -= bound(ent->fields.client->mins[0], eorg[0], ent->fields.client->maxs[0]);
307 eorg[1] -= bound(ent->fields.client->mins[1], eorg[1], ent->fields.client->maxs[1]);
308 eorg[2] -= bound(ent->fields.client->mins[2], eorg[2], ent->fields.client->maxs[2]);
311 VectorMAMAM(1, eorg, 0.5f, ent->fields.client->mins, 0.5f, ent->fields.client->maxs, eorg);
312 if (DotProduct(eorg, eorg) < radius2)
314 ent->fields.client->chain = PRVM_EDICT_TO_PROG(chain);
319 VM_RETURN_EDICT(chain);
322 // #34 float() droptofloor
323 void VM_CL_droptofloor (void)
330 // assume failure if it returns early
331 PRVM_G_FLOAT(OFS_RETURN) = 0;
333 ent = PRVM_PROG_TO_EDICT(prog->globals.client->self);
334 if (ent == prog->edicts)
336 VM_Warning("droptofloor: can not modify world entity\n");
339 if (ent->priv.server->free)
341 VM_Warning("droptofloor: can not modify free entity\n");
345 VectorCopy (ent->fields.client->origin, end);
348 trace = CL_TraceBox(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->maxs, end, 1, &i, 1, false);
350 if (trace.fraction != 1)
352 VectorCopy (trace.endpos, ent->fields.client->origin);
353 ent->fields.client->flags = (int)ent->fields.client->flags | FL_ONGROUND;
354 // ent->fields.client->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
355 PRVM_G_FLOAT(OFS_RETURN) = 1;
356 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
357 // ent->priv.server->suspendedinairflag = true;
361 // #35 void(float style, string value) lightstyle
362 void VM_CL_lightstyle (void)
367 VM_SAFEPARMCOUNT(2, VM_CL_lightstyle);
369 i = (int)PRVM_G_FLOAT(OFS_PARM0);
370 c = PRVM_G_STRING(OFS_PARM1);
371 if (i >= cl.max_lightstyle)
373 VM_Warning("VM_CL_lightstyle >= MAX_LIGHTSTYLES\n");
376 strlcpy (cl.lightstyle[i].map, MSG_ReadString(), sizeof (cl.lightstyle[i].map));
377 cl.lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
378 cl.lightstyle[i].length = (int)strlen(cl.lightstyle[i].map);
381 // #40 float(entity e) checkbottom
382 void VM_CL_checkbottom (void)
384 static int cs_yes, cs_no;
386 vec3_t mins, maxs, start, stop;
391 VM_SAFEPARMCOUNT(1, VM_CL_checkbottom);
392 ent = PRVM_G_EDICT(OFS_PARM0);
393 PRVM_G_FLOAT(OFS_RETURN) = 0;
395 VectorAdd (ent->fields.client->origin, ent->fields.client->mins, mins);
396 VectorAdd (ent->fields.client->origin, ent->fields.client->maxs, maxs);
398 // if all of the points under the corners are solid world, don't bother
399 // with the tougher checks
400 // the corners must be within 16 of the midpoint
401 start[2] = mins[2] - 1;
402 for (x=0 ; x<=1 ; x++)
403 for (y=0 ; y<=1 ; y++)
405 start[0] = x ? maxs[0] : mins[0];
406 start[1] = y ? maxs[1] : mins[1];
407 if (!(CL_PointSuperContents(start) & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY)))
412 PRVM_G_FLOAT(OFS_RETURN) = true;
413 return; // we got out easy
418 // check it for real...
422 // the midpoint must be within 16 of the bottom
423 start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
424 start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
425 stop[2] = start[2] - 2*sv_stepheight.value;
426 trace = CL_TraceBox (start, vec3_origin, vec3_origin, stop, 1, &hit, 1, true);
428 if (trace.fraction == 1.0)
431 mid = bottom = trace.endpos[2];
433 // the corners must be within 16 of the midpoint
434 for (x=0 ; x<=1 ; x++)
435 for (y=0 ; y<=1 ; y++)
437 start[0] = stop[0] = x ? maxs[0] : mins[0];
438 start[1] = stop[1] = y ? maxs[1] : mins[1];
440 trace = CL_TraceBox (start, vec3_origin, vec3_origin, stop, 1, &hit, 1, true);
442 if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
443 bottom = trace.endpos[2];
444 if (trace.fraction == 1.0 || mid - trace.endpos[2] > sv_stepheight.value)
449 PRVM_G_FLOAT(OFS_RETURN) = true;
452 // #41 float(vector v) pointcontents
453 void VM_CL_pointcontents (void)
455 VM_SAFEPARMCOUNT(1, VM_CL_pointcontents);
456 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, CL_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
459 // #48 void(vector o, vector d, float color, float count) particle
460 void VM_CL_particle (void)
465 VM_SAFEPARMCOUNT(4, VM_CL_particle);
467 org = PRVM_G_VECTOR(OFS_PARM0);
468 dir = PRVM_G_VECTOR(OFS_PARM1);
469 color = (int)PRVM_G_FLOAT(OFS_PARM2);
470 count = (int)PRVM_G_FLOAT(OFS_PARM3);
471 CL_ParticleEffect(EFFECT_SVC_PARTICLE, count, org, org, dir, dir, NULL, color);
474 // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
475 void VM_CL_tracetoss (void)
479 prvm_edict_t *ignore;
481 ent = PRVM_G_EDICT(OFS_PARM0);
482 if (ent == prog->edicts)
484 VM_Warning("tracetoss: can not use world entity\n");
487 ignore = PRVM_G_EDICT(OFS_PARM1);
490 trace = SV_Trace_Toss (ent, ignore);
492 prog->globals.server->trace_allsolid = trace.allsolid;
493 prog->globals.server->trace_startsolid = trace.startsolid;
494 prog->globals.server->trace_fraction = trace.fraction;
495 prog->globals.server->trace_inwater = trace.inwater;
496 prog->globals.server->trace_inopen = trace.inopen;
497 VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
498 VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
499 prog->globals.server->trace_plane_dist = trace.plane.dist;
501 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
503 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
507 // #74 void(vector pos, string samp, float vol, float atten) ambientsound
508 void VM_CL_ambientsound (void)
512 VM_SAFEPARMCOUNT(4, VM_CL_ambientsound);
513 s = S_FindName(PRVM_G_STRING(OFS_PARM0));
514 f = PRVM_G_VECTOR(OFS_PARM1);
515 S_StaticSound (s, f, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3)*64);
518 // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
519 void VM_CL_tracebox (void)
521 float *v1, *v2, *m1, *m2;
525 v1 = PRVM_G_VECTOR(OFS_PARM0);
526 m1 = PRVM_G_VECTOR(OFS_PARM1);
527 m2 = PRVM_G_VECTOR(OFS_PARM2);
528 v2 = PRVM_G_VECTOR(OFS_PARM3);
530 trace = CL_TraceBox(v1, m1, m2, v2, 1, &ent, 1, false);
532 prog->globals.client->trace_allsolid = trace.allsolid;
533 prog->globals.client->trace_startsolid = trace.startsolid;
534 prog->globals.client->trace_fraction = trace.fraction;
535 prog->globals.client->trace_inwater = trace.inwater;
536 prog->globals.client->trace_inopen = trace.inopen;
537 VectorCopy (trace.endpos, prog->globals.client->trace_endpos);
538 VectorCopy (trace.plane.normal, prog->globals.client->trace_plane_normal);
539 prog->globals.client->trace_plane_dist = trace.plane.dist;
541 prog->globals.client->trace_ent = ent;
543 prog->globals.client->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
546 // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
547 void VM_CL_getlight (void)
549 vec3_t ambientcolor, diffusecolor, diffusenormal;
552 VM_SAFEPARMCOUNT(1, VM_CL_getlight);
554 p = PRVM_G_VECTOR(OFS_PARM0);
555 VectorClear(ambientcolor);
556 VectorClear(diffusecolor);
557 VectorClear(diffusenormal);
558 if (cl.worldmodel && cl.worldmodel->brush.LightPoint)
559 cl.worldmodel->brush.LightPoint(cl.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
560 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
564 //============================================================================
565 //[515]: SCENE MANAGER builtins
566 extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed);//csprogs.c
568 matrix4x4_t csqc_listenermatrix;
569 qboolean csqc_usecsqclistener = false;//[515]: per-frame
571 static void CSQC_R_RecalcView (void)
573 extern matrix4x4_t viewmodelmatrix;
574 Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 1);
575 Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], cl_viewmodel_scale.value);
578 void CL_RelinkLightFlashes(void);
579 //#300 void() clearscene (EXT_CSQC)
580 void VM_R_ClearScene (void)
582 VM_SAFEPARMCOUNT(0, VM_R_ClearScene);
583 // clear renderable entity and light lists
584 r_refdef.numentities = 0;
585 r_refdef.numlights = 0;
588 //#301 void(float mask) addentities (EXT_CSQC)
589 extern void CSQC_Predraw (prvm_edict_t *ed);//csprogs.c
590 extern void CSQC_Think (prvm_edict_t *ed);//csprogs.c
591 void VM_R_AddEntities (void)
595 VM_SAFEPARMCOUNT(1, VM_R_AddEntities);
596 drawmask = (int)PRVM_G_FLOAT(OFS_PARM0);
597 CSQC_RelinkAllEntities(drawmask);
598 CL_RelinkLightFlashes();
600 prog->globals.client->time = cl.time;
601 for(i=1;i<prog->num_edicts;i++)
603 ed = &prog->edicts[i];
604 if(ed->priv.required->free)
606 VectorAdd(ed->fields.client->origin, ed->fields.client->mins, ed->fields.client->absmin);
607 VectorAdd(ed->fields.client->origin, ed->fields.client->maxs, ed->fields.client->absmax);
609 if(ed->priv.required->free)
611 // note that for RF_USEAXIS entities, Predraw sets v_forward/v_right/v_up globals that are read by CSQC_AddRenderEdict
613 if(ed->priv.required->free)
615 if(!((int)ed->fields.client->drawmask & drawmask))
617 CSQC_AddRenderEdict(ed);
621 //#302 void(entity ent) addentity (EXT_CSQC)
622 void VM_R_AddEntity (void)
624 VM_SAFEPARMCOUNT(1, VM_R_AddEntity);
625 CSQC_AddRenderEdict(PRVM_G_EDICT(OFS_PARM0));
628 //#303 float(float property, ...) setproperty (EXT_CSQC)
629 void VM_R_SetView (void)
636 VM_SAFEPARMCOUNT(2, VM_R_SetView);
638 c = (int)PRVM_G_FLOAT(OFS_PARM0);
639 f = PRVM_G_VECTOR(OFS_PARM1);
640 k = PRVM_G_FLOAT(OFS_PARM1);
644 case VF_MIN: r_view.x = (int)f[0];
645 r_view.y = (int)f[1];
647 case VF_MIN_X: r_view.x = (int)k;
649 case VF_MIN_Y: r_view.y = (int)k;
651 case VF_SIZE: r_view.width = (int)f[0];
652 r_view.height = (int)f[1];
654 case VF_SIZE_Y: r_view.width = (int)k;
656 case VF_SIZE_X: r_view.height = (int)k;
658 case VF_VIEWPORT: r_view.x = (int)f[0];
659 r_view.y = (int)f[1];
661 // TODO: make sure that view_z and view_depth are set properly even if csqc does not set them!
662 f = PRVM_G_VECTOR(OFS_PARM2);
663 r_view.width = (int)f[0];
664 r_view.height = (int)f[1];
667 case VF_FOV: //r_refdef.fov_x = f[0]; // FIXME!
668 //r_refdef.fov_y = f[1]; // FIXME!
670 case VF_FOVX: //r_refdef.fov_x = k; // FIXME!
672 case VF_FOVY: //r_refdef.fov_y = k; // FIXME!
674 case VF_ORIGIN: VectorCopy(f, csqc_origin);
677 case VF_ORIGIN_X: csqc_origin[0] = k;
680 case VF_ORIGIN_Y: csqc_origin[1] = k;
683 case VF_ORIGIN_Z: csqc_origin[2] = k;
686 case VF_ANGLES: VectorCopy(f, csqc_angles);
689 case VF_ANGLES_X: csqc_angles[0] = k;
692 case VF_ANGLES_Y: csqc_angles[1] = k;
695 case VF_ANGLES_Z: csqc_angles[2] = k;
698 case VF_DRAWWORLD: cl.csqc_vidvars.drawworld = k;
700 case VF_DRAWENGINESBAR: cl.csqc_vidvars.drawenginesbar = k;
702 case VF_DRAWCROSSHAIR: cl.csqc_vidvars.drawcrosshair = k;
705 case VF_CL_VIEWANGLES: VectorCopy(f, cl.viewangles);
707 case VF_CL_VIEWANGLES_X:cl.viewangles[0] = k;
709 case VF_CL_VIEWANGLES_Y:cl.viewangles[1] = k;
711 case VF_CL_VIEWANGLES_Z:cl.viewangles[2] = k;
714 default: PRVM_G_FLOAT(OFS_RETURN) = 0;
715 VM_Warning("VM_R_SetView : unknown parm %i\n", c);
718 PRVM_G_FLOAT(OFS_RETURN) = 1;
721 extern void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit);
722 //#304 void() renderscene (EXT_CSQC)
723 void VM_R_RenderScene (void) //#134
726 VM_SAFEPARMCOUNT(0, VM_R_RenderScene);
727 // we need to update any RENDER_VIEWMODEL entities at this point because
728 // csqc supplies its own view matrix
729 for (i = 1;i < cl.num_entities;i++)
731 if (cl.entities_active[i])
733 entity_t *ent = cl.entities + i;
734 if ((ent->render.flags & RENDER_VIEWMODEL) || ent->state_current.tagentity)
735 CL_UpdateNetworkEntity(ent, 32);
738 // and of course the engine viewmodel needs updating as well
739 CL_UpdateNetworkEntity(&cl.viewent, 32);
744 //#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
745 void VM_R_AddDynamicLight (void)
749 VM_SAFEPARMCOUNT(3, VM_R_AddDynamicLight);
751 // if we've run out of dlights, just return
752 if (r_refdef.numlights >= MAX_DLIGHTS)
755 pos = PRVM_G_VECTOR(OFS_PARM0);
756 col = PRVM_G_VECTOR(OFS_PARM2);
757 Matrix4x4_CreateFromQuakeEntity(&matrix, pos[0], pos[1], pos[2], 0, 0, 0, PRVM_G_FLOAT(OFS_PARM1));
758 R_RTLight_Update(&r_refdef.lights[r_refdef.numlights++], false, &matrix, col, -1, NULL, true, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
761 //============================================================================
763 //#310 vector (vector v) cs_unproject (EXT_CSQC)
764 void VM_CL_unproject (void)
769 VM_SAFEPARMCOUNT(1, VM_CL_unproject);
770 f = PRVM_G_VECTOR(OFS_PARM0);
771 VectorSet(temp, f[2], f[0] * f[2] * -r_view.frustum_x * 2.0 / r_view.width, f[1] * f[2] * -r_view.frustum_y * 2.0 / r_view.height);
772 Matrix4x4_Transform(&r_view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
775 //#311 vector (vector v) cs_project (EXT_CSQC)
776 void VM_CL_project (void)
782 VM_SAFEPARMCOUNT(1, VM_CL_project);
783 f = PRVM_G_VECTOR(OFS_PARM0);
784 Matrix4x4_Invert_Simple(&m, &r_view.matrix);
785 Matrix4x4_Transform(&m, f, v);
786 VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_view.frustum_x*0.5*r_view.width, v[2]/v[0]/-r_view.frustum_y*r_view.height*0.5, v[0]);
789 //#330 float(float stnum) getstatf (EXT_CSQC)
790 void VM_CL_getstatf (void)
798 VM_SAFEPARMCOUNT(1, VM_CL_getstatf);
799 i = (int)PRVM_G_FLOAT(OFS_PARM0);
800 if(i < 0 || i >= MAX_CL_STATS)
802 VM_Warning("VM_CL_getstatf: index>=MAX_CL_STATS or index<0\n");
806 PRVM_G_FLOAT(OFS_RETURN) = dat.f;
809 //#331 float(float stnum) getstati (EXT_CSQC)
810 void VM_CL_getstati (void)
813 VM_SAFEPARMCOUNT(1, VM_CL_getstati);
814 index = (int)PRVM_G_FLOAT(OFS_PARM0);
816 if(index < 0 || index >= MAX_CL_STATS)
818 VM_Warning("VM_CL_getstati: index>=MAX_CL_STATS or index<0\n");
822 PRVM_G_FLOAT(OFS_RETURN) = i;
825 //#332 string(float firststnum) getstats (EXT_CSQC)
826 void VM_CL_getstats (void)
830 VM_SAFEPARMCOUNT(1, VM_CL_getstats);
831 i = (int)PRVM_G_FLOAT(OFS_PARM0);
832 if(i < 0 || i > MAX_CL_STATS-4)
834 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
835 VM_Warning("VM_CL_getstats: index>MAX_CL_STATS-4 or index<0\n");
838 strlcpy(t, (char*)&cl.stats[i], sizeof(t));
839 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
842 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
843 void VM_CL_setmodelindex (void)
847 struct model_s *model;
849 VM_SAFEPARMCOUNT(2, VM_CL_setmodelindex);
851 t = PRVM_G_EDICT(OFS_PARM0);
853 i = (int)PRVM_G_FLOAT(OFS_PARM1);
855 t->fields.client->model = 0;
856 t->fields.client->modelindex = 0;
861 model = CSQC_GetModelByIndex(i);
864 VM_Warning("VM_CL_setmodelindex: null model\n");
867 t->fields.client->model = PRVM_SetEngineString(model->name);
868 t->fields.client->modelindex = i;
871 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
872 void VM_CL_modelnameforindex (void)
876 VM_SAFEPARMCOUNT(1, VM_CL_modelnameforindex);
878 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
879 model = CSQC_GetModelByIndex((int)PRVM_G_FLOAT(OFS_PARM0));
880 PRVM_G_INT(OFS_RETURN) = model ? PRVM_SetEngineString(model->name) : 0;
883 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
884 void VM_CL_particleeffectnum (void)
887 VM_SAFEPARMCOUNT(1, VM_CL_particleeffectnum);
888 i = CL_ParticleEffectIndexForName(PRVM_G_STRING(OFS_PARM0));
891 PRVM_G_FLOAT(OFS_RETURN) = i;
894 // #336 void(entity ent, float effectnum, vector start, vector end[, float color]) trailparticles (EXT_CSQC)
895 void VM_CL_trailparticles (void)
900 VM_SAFEPARMCOUNT(4, VM_CL_trailparticles);
902 t = PRVM_G_EDICT(OFS_PARM0);
903 i = (int)PRVM_G_FLOAT(OFS_PARM1);
904 start = PRVM_G_VECTOR(OFS_PARM2);
905 end = PRVM_G_VECTOR(OFS_PARM3);
907 CL_ParticleEffect(i, VectorDistance(start, end), start, end, t->fields.client->velocity, t->fields.client->velocity, NULL, (int)PRVM_G_FLOAT(OFS_PARM4));
910 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
911 void VM_CL_pointparticles (void)
915 VM_SAFEPARMCOUNT(4, VM_CL_pointparticles);
916 i = (int)PRVM_G_FLOAT(OFS_PARM0);
917 f = PRVM_G_VECTOR(OFS_PARM1);
918 v = PRVM_G_VECTOR(OFS_PARM2);
919 n = (int)PRVM_G_FLOAT(OFS_PARM3);
920 CL_ParticleEffect(i, n, f, f, v, v, NULL, 0);
923 //#338 void(string s) cprint (EXT_CSQC)
924 void VM_CL_centerprint (void)
926 char s[VM_STRINGTEMP_LENGTH];
928 VM_SAFEPARMCOUNT(1, VM_CL_centerprint);
929 VM_VarString(0, s, sizeof(s));
933 //#342 string(float keynum) getkeybind (EXT_CSQC)
934 void VM_CL_getkeybind (void)
936 VM_SAFEPARMCOUNT(1, VM_CL_getkeybind);
937 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0)));
940 //#343 void(float usecursor) setcursormode (EXT_CSQC)
941 void VM_CL_setcursormode (void)
943 VM_SAFEPARMCOUNT(1, VM_CL_setcursormode);
944 cl.csqc_wantsmousemove = PRVM_G_FLOAT(OFS_PARM0);
945 cl_ignoremousemove = true;
948 //#345 float(float framenum) getinputstate (EXT_CSQC)
949 void VM_CL_getinputstate (void)
952 VM_SAFEPARMCOUNT(1, VM_CL_getinputstate);
953 frame = (int)PRVM_G_FLOAT(OFS_PARM0);
954 for (i = 0;i < cl.movement_numqueue;i++)
955 if (cl.movement_queue[i].sequence == frame)
957 VectorCopy(cl.movement_queue[i].viewangles, prog->globals.client->input_angles);
958 //prog->globals.client->input_buttons = cl.movement_queue[i].//FIXME
959 VectorCopy(cl.movement_queue[i].move, prog->globals.client->input_movevalues);
960 prog->globals.client->input_timelength = cl.movement_queue[i].frametime;
961 if(cl.movement_queue[i].crouch)
963 VectorCopy(cl.playercrouchmins, prog->globals.client->pmove_mins);
964 VectorCopy(cl.playercrouchmaxs, prog->globals.client->pmove_maxs);
968 VectorCopy(cl.playerstandmins, prog->globals.client->pmove_mins);
969 VectorCopy(cl.playerstandmaxs, prog->globals.client->pmove_maxs);
974 //#346 void(float sens) setsensitivityscaler (EXT_CSQC)
975 void VM_CL_setsensitivityscale (void)
977 VM_SAFEPARMCOUNT(1, VM_CL_setsensitivityscale);
978 cl.sensitivityscale = PRVM_G_FLOAT(OFS_PARM0);
981 //#347 void() runstandardplayerphysics (EXT_CSQC)
982 void VM_CL_runplayerphysics (void)
986 //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
987 void VM_CL_getplayerkey (void)
993 VM_SAFEPARMCOUNT(2, VM_CL_getplayerkey);
995 i = (int)PRVM_G_FLOAT(OFS_PARM0);
996 c = PRVM_G_STRING(OFS_PARM1);
997 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
1000 i = Sbar_GetPlayer(i);
1006 if(!strcasecmp(c, "name"))
1007 strlcpy(t, cl.scores[i].name, sizeof(t));
1009 if(!strcasecmp(c, "frags"))
1010 sprintf(t, "%i", cl.scores[i].frags);
1012 if(!strcasecmp(c, "ping"))
1013 sprintf(t, "%i", cl.scores[i].qw_ping);
1015 if(!strcasecmp(c, "entertime"))
1016 sprintf(t, "%f", cl.scores[i].qw_entertime);
1018 if(!strcasecmp(c, "colors"))
1019 sprintf(t, "%i", cl.scores[i].colors);
1021 if(!strcasecmp(c, "topcolor"))
1022 sprintf(t, "%i", cl.scores[i].colors & 0xf0);
1024 if(!strcasecmp(c, "bottomcolor"))
1025 sprintf(t, "%i", (cl.scores[i].colors &15)<<4);
1027 if(!strcasecmp(c, "viewentity"))
1028 sprintf(t, "%i", i+1);
1031 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
1034 //#349 float() isdemo (EXT_CSQC)
1035 void VM_CL_isdemo (void)
1037 PRVM_G_FLOAT(OFS_RETURN) = cls.demoplayback;
1040 //#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
1041 void VM_CL_setlistener (void)
1043 VM_SAFEPARMCOUNT(4, VM_CL_setlistener);
1044 Matrix4x4_FromVectors(&csqc_listenermatrix, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), PRVM_G_VECTOR(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0));
1045 csqc_usecsqclistener = true; //use csqc listener at this frame
1048 //#352 void(string cmdname) registercommand (EXT_CSQC)
1049 void VM_CL_registercmd (void)
1052 VM_SAFEPARMCOUNT(1, VM_CL_registercmd);
1053 if(!Cmd_Exists(PRVM_G_STRING(OFS_PARM0)))
1057 alloclen = strlen(PRVM_G_STRING(OFS_PARM0)) + 1;
1058 t = (char *)Z_Malloc(alloclen);
1059 memcpy(t, PRVM_G_STRING(OFS_PARM0), alloclen);
1060 Cmd_AddCommand(t, NULL, "console command created by QuakeC");
1063 Cmd_AddCommand(PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
1067 //#354 float() playernum (EXT_CSQC)
1068 void VM_CL_playernum (void)
1072 VM_SAFEPARMCOUNT(0, VM_CL_playernum);
1074 for(i=k=0 ; i<cl.maxclients ; i++)
1075 if(cl.scores[i].name[0])
1077 PRVM_G_FLOAT(OFS_RETURN) = k;
1080 //#355 float() cl_onground (EXT_CSQC)
1081 void VM_CL_onground (void)
1083 PRVM_G_FLOAT(OFS_RETURN) = cl.onground;
1086 //#360 float() readbyte (EXT_CSQC)
1087 void VM_CL_ReadByte (void)
1089 PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadByte();
1092 //#361 float() readchar (EXT_CSQC)
1093 void VM_CL_ReadChar (void)
1095 PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar();
1098 //#362 float() readshort (EXT_CSQC)
1099 void VM_CL_ReadShort (void)
1101 PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadShort();
1104 //#363 float() readlong (EXT_CSQC)
1105 void VM_CL_ReadLong (void)
1107 PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadLong();
1110 //#364 float() readcoord (EXT_CSQC)
1111 void VM_CL_ReadCoord (void)
1113 PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadCoord(cls.protocol);
1116 //#365 float() readangle (EXT_CSQC)
1117 void VM_CL_ReadAngle (void)
1119 PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadAngle(cls.protocol);
1122 //#366 string() readstring (EXT_CSQC)
1123 void VM_CL_ReadString (void)
1125 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(MSG_ReadString());
1128 //#367 float() readfloat (EXT_CSQC)
1129 void VM_CL_ReadFloat (void)
1131 PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadFloat();
1134 //=================================================================//
1136 // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
1137 void VM_CL_effect (void)
1139 VM_SAFEPARMCOUNT(5, VM_CL_effect);
1140 CL_Effect(PRVM_G_VECTOR(OFS_PARM0), (int)PRVM_G_FLOAT(OFS_PARM1), (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4));
1143 // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
1144 void VM_CL_te_blood (void)
1148 VM_SAFEPARMCOUNT(3, VM_CL_te_blood);
1149 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1151 pos = PRVM_G_VECTOR(OFS_PARM0);
1152 CL_FindNonSolidLocation(pos, pos2, 4);
1153 CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
1156 // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
1157 void VM_CL_te_bloodshower (void)
1161 VM_SAFEPARMCOUNT(4, VM_CL_te_bloodshower);
1162 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1164 speed = PRVM_G_FLOAT(OFS_PARM2);
1171 CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), vel1, vel2, NULL, 0);
1174 // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
1175 void VM_CL_te_explosionrgb (void)
1179 matrix4x4_t tempmatrix;
1180 VM_SAFEPARMCOUNT(2, VM_CL_te_explosionrgb);
1181 pos = PRVM_G_VECTOR(OFS_PARM0);
1182 CL_FindNonSolidLocation(pos, pos2, 10);
1183 CL_ParticleExplosion(pos2);
1184 Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
1185 CL_AllocLightFlash(NULL, &tempmatrix, 350, PRVM_G_VECTOR(OFS_PARM1)[0], PRVM_G_VECTOR(OFS_PARM1)[1], PRVM_G_VECTOR(OFS_PARM1)[2], 700, 0.5, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1188 // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
1189 void VM_CL_te_particlecube (void)
1191 VM_SAFEPARMCOUNT(7, VM_CL_te_particlecube);
1192 CL_ParticleCube(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), PRVM_G_FLOAT(OFS_PARM5), PRVM_G_FLOAT(OFS_PARM6));
1195 // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
1196 void VM_CL_te_particlerain (void)
1198 VM_SAFEPARMCOUNT(5, VM_CL_te_particlerain);
1199 CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 0);
1202 // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
1203 void VM_CL_te_particlesnow (void)
1205 VM_SAFEPARMCOUNT(5, VM_CL_te_particlesnow);
1206 CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 1);
1209 // #411 void(vector org, vector vel, float howmany) te_spark
1210 void VM_CL_te_spark (void)
1214 VM_SAFEPARMCOUNT(3, VM_CL_te_spark);
1216 pos = PRVM_G_VECTOR(OFS_PARM0);
1217 CL_FindNonSolidLocation(pos, pos2, 4);
1218 CL_ParticleEffect(EFFECT_TE_SPARK, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
1221 // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
1222 void VM_CL_te_gunshotquad (void)
1226 VM_SAFEPARMCOUNT(1, VM_CL_te_gunshotquad);
1228 pos = PRVM_G_VECTOR(OFS_PARM0);
1229 CL_FindNonSolidLocation(pos, pos2, 4);
1230 CL_ParticleEffect(EFFECT_TE_GUNSHOTQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1233 // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
1234 void VM_CL_te_spikequad (void)
1239 VM_SAFEPARMCOUNT(1, VM_CL_te_spikequad);
1241 pos = PRVM_G_VECTOR(OFS_PARM0);
1242 CL_FindNonSolidLocation(pos, pos2, 4);
1243 CL_ParticleEffect(EFFECT_TE_SPIKEQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1244 if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
1248 if (rnd == 1) S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
1249 else if (rnd == 2) S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
1250 else S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
1254 // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
1255 void VM_CL_te_superspikequad (void)
1260 VM_SAFEPARMCOUNT(1, VM_CL_te_superspikequad);
1262 pos = PRVM_G_VECTOR(OFS_PARM0);
1263 CL_FindNonSolidLocation(pos, pos2, 4);
1264 CL_ParticleEffect(EFFECT_TE_SUPERSPIKEQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1265 if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos, 1, 1);
1269 if (rnd == 1) S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
1270 else if (rnd == 2) S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
1271 else S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
1275 // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
1276 void VM_CL_te_explosionquad (void)
1280 VM_SAFEPARMCOUNT(1, VM_CL_te_explosionquad);
1282 pos = PRVM_G_VECTOR(OFS_PARM0);
1283 CL_FindNonSolidLocation(pos, pos2, 10);
1284 CL_ParticleEffect(EFFECT_TE_EXPLOSIONQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1285 S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
1288 // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
1289 void VM_CL_te_smallflash (void)
1293 VM_SAFEPARMCOUNT(1, VM_CL_te_smallflash);
1295 pos = PRVM_G_VECTOR(OFS_PARM0);
1296 CL_FindNonSolidLocation(pos, pos2, 10);
1297 CL_ParticleEffect(EFFECT_TE_SMALLFLASH, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1300 // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
1301 void VM_CL_te_customflash (void)
1305 matrix4x4_t tempmatrix;
1306 VM_SAFEPARMCOUNT(4, VM_CL_te_customflash);
1308 pos = PRVM_G_VECTOR(OFS_PARM0);
1309 CL_FindNonSolidLocation(pos, pos2, 4);
1310 Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
1311 CL_AllocLightFlash(NULL, &tempmatrix, PRVM_G_FLOAT(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM3)[0], PRVM_G_VECTOR(OFS_PARM3)[1], PRVM_G_VECTOR(OFS_PARM3)[2], PRVM_G_FLOAT(OFS_PARM1) / PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM2), 0, -1, true, 1, 0.25, 1, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1314 // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
1315 void VM_CL_te_gunshot (void)
1319 VM_SAFEPARMCOUNT(1, VM_CL_te_gunshot);
1321 pos = PRVM_G_VECTOR(OFS_PARM0);
1322 CL_FindNonSolidLocation(pos, pos2, 4);
1323 CL_ParticleEffect(EFFECT_TE_GUNSHOT, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1326 // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
1327 void VM_CL_te_spike (void)
1332 VM_SAFEPARMCOUNT(1, VM_CL_te_spike);
1334 pos = PRVM_G_VECTOR(OFS_PARM0);
1335 CL_FindNonSolidLocation(pos, pos2, 4);
1336 CL_ParticleEffect(EFFECT_TE_SPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1337 if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
1341 if (rnd == 1) S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
1342 else if (rnd == 2) S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
1343 else S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
1347 // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
1348 void VM_CL_te_superspike (void)
1353 VM_SAFEPARMCOUNT(1, VM_CL_te_superspike);
1355 pos = PRVM_G_VECTOR(OFS_PARM0);
1356 CL_FindNonSolidLocation(pos, pos2, 4);
1357 CL_ParticleEffect(EFFECT_TE_SUPERSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1358 if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
1362 if (rnd == 1) S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
1363 else if (rnd == 2) S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
1364 else S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
1368 // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
1369 void VM_CL_te_explosion (void)
1373 VM_SAFEPARMCOUNT(1, VM_CL_te_explosion);
1375 pos = PRVM_G_VECTOR(OFS_PARM0);
1376 CL_FindNonSolidLocation(pos, pos2, 10);
1377 CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1378 S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
1381 // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
1382 void VM_CL_te_tarexplosion (void)
1386 VM_SAFEPARMCOUNT(1, VM_CL_te_tarexplosion);
1388 pos = PRVM_G_VECTOR(OFS_PARM0);
1389 CL_FindNonSolidLocation(pos, pos2, 10);
1390 CL_ParticleEffect(EFFECT_TE_TAREXPLOSION, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1391 S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
1394 // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
1395 void VM_CL_te_wizspike (void)
1399 VM_SAFEPARMCOUNT(1, VM_CL_te_wizspike);
1401 pos = PRVM_G_VECTOR(OFS_PARM0);
1402 CL_FindNonSolidLocation(pos, pos2, 4);
1403 CL_ParticleEffect(EFFECT_TE_WIZSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1404 S_StartSound(-1, 0, cl.sfx_wizhit, pos2, 1, 1);
1407 // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
1408 void VM_CL_te_knightspike (void)
1412 VM_SAFEPARMCOUNT(1, VM_CL_te_knightspike);
1414 pos = PRVM_G_VECTOR(OFS_PARM0);
1415 CL_FindNonSolidLocation(pos, pos2, 4);
1416 CL_ParticleEffect(EFFECT_TE_KNIGHTSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1417 S_StartSound(-1, 0, cl.sfx_knighthit, pos2, 1, 1);
1420 // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
1421 void VM_CL_te_lavasplash (void)
1423 VM_SAFEPARMCOUNT(1, VM_CL_te_lavasplash);
1424 CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
1427 // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
1428 void VM_CL_te_teleport (void)
1430 VM_SAFEPARMCOUNT(1, VM_CL_te_teleport);
1431 CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
1434 // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
1435 void VM_CL_te_explosion2 (void)
1439 matrix4x4_t tempmatrix;
1440 int colorStart, colorLength;
1441 unsigned char *tempcolor;
1442 VM_SAFEPARMCOUNT(3, VM_CL_te_explosion2);
1444 pos = PRVM_G_VECTOR(OFS_PARM0);
1445 colorStart = (int)PRVM_G_FLOAT(OFS_PARM1);
1446 colorLength = (int)PRVM_G_FLOAT(OFS_PARM2);
1447 CL_FindNonSolidLocation(pos, pos2, 10);
1448 CL_ParticleExplosion2(pos2, colorStart, colorLength);
1449 tempcolor = (unsigned char *)&palette_complete[(rand()%colorLength) + colorStart];
1450 color[0] = tempcolor[0] * (2.0f / 255.0f);
1451 color[1] = tempcolor[1] * (2.0f / 255.0f);
1452 color[2] = tempcolor[2] * (2.0f / 255.0f);
1453 Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
1454 CL_AllocLightFlash(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1455 S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
1459 // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
1460 void VM_CL_te_lightning1 (void)
1462 VM_SAFEPARMCOUNT(3, VM_CL_te_lightning1);
1463 CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt, true);
1466 // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
1467 void VM_CL_te_lightning2 (void)
1469 VM_SAFEPARMCOUNT(3, VM_CL_te_lightning2);
1470 CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt2, true);
1473 // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
1474 void VM_CL_te_lightning3 (void)
1476 VM_SAFEPARMCOUNT(3, VM_CL_te_lightning3);
1477 CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt3, false);
1480 // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
1481 void VM_CL_te_beam (void)
1483 VM_SAFEPARMCOUNT(3, VM_CL_te_beam);
1484 CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_beam, false);
1487 // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
1488 void VM_CL_te_plasmaburn (void)
1492 VM_SAFEPARMCOUNT(1, VM_CL_te_plasmaburn);
1494 pos = PRVM_G_VECTOR(OFS_PARM0);
1495 CL_FindNonSolidLocation(pos, pos2, 4);
1496 CL_ParticleEffect(EFFECT_TE_PLASMABURN, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1500 //====================================================================
1503 extern void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out);
1505 static msurface_t *cl_getsurface(model_t *model, int surfacenum)
1507 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
1509 return model->data_surfaces + surfacenum + model->firstmodelsurface;
1512 // #434 float(entity e, float s) getsurfacenumpoints
1513 void VM_CL_getsurfacenumpoints(void)
1515 model_t *model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0));
1516 msurface_t *surface;
1517 // return 0 if no such surface
1518 if (!model || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1520 PRVM_G_FLOAT(OFS_RETURN) = 0;
1524 // note: this (incorrectly) assumes it is a simple polygon
1525 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
1528 // #435 vector(entity e, float s, float n) getsurfacepoint
1529 void VM_CL_getsurfacepoint(void)
1533 msurface_t *surface;
1535 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
1536 ed = PRVM_G_EDICT(OFS_PARM0);
1537 if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1539 // note: this (incorrectly) assumes it is a simple polygon
1540 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
1541 if (pointnum < 0 || pointnum >= surface->num_vertices)
1543 // FIXME: implement rotation/scaling
1544 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.client->origin, PRVM_G_VECTOR(OFS_RETURN));
1547 // #436 vector(entity e, float s) getsurfacenormal
1548 void VM_CL_getsurfacenormal(void)
1551 msurface_t *surface;
1553 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
1554 if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1556 // FIXME: implement rotation/scaling
1557 // note: this (incorrectly) assumes it is a simple polygon
1558 // note: this only returns the first triangle, so it doesn't work very
1559 // well for curved surfaces or arbitrary meshes
1560 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);
1561 VectorNormalize(normal);
1562 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
1565 // #437 string(entity e, float s) getsurfacetexture
1566 void VM_CL_getsurfacetexture(void)
1569 msurface_t *surface;
1570 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
1571 if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1573 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
1576 // #438 float(entity e, vector p) getsurfacenearpoint
1577 void VM_CL_getsurfacenearpoint(void)
1579 int surfacenum, best;
1581 vec_t dist, bestdist;
1583 model_t *model = NULL;
1584 msurface_t *surface;
1586 PRVM_G_FLOAT(OFS_RETURN) = -1;
1587 ed = PRVM_G_EDICT(OFS_PARM0);
1588 if(!(model = CSQC_GetModelFromEntity(ed)) || !model->num_surfaces)
1591 // FIXME: implement rotation/scaling
1592 point = PRVM_G_VECTOR(OFS_PARM1);
1593 VectorSubtract(point, ed->fields.client->origin, p);
1595 bestdist = 1000000000;
1596 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
1598 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
1599 // first see if the nearest point on the surface's box is closer than the previous match
1600 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
1601 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
1602 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
1603 dist = VectorLength2(clipped);
1604 if (dist < bestdist)
1606 // it is, check the nearest point on the actual geometry
1607 clippointtosurface(model, surface, p, clipped);
1608 VectorSubtract(clipped, p, clipped);
1609 dist += VectorLength2(clipped);
1610 if (dist < bestdist)
1612 // that's closer too, store it as the best match
1618 PRVM_G_FLOAT(OFS_RETURN) = best;
1621 // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint
1622 void VM_CL_getsurfaceclippedpoint(void)
1626 msurface_t *surface;
1628 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
1629 ed = PRVM_G_EDICT(OFS_PARM0);
1630 if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1632 // FIXME: implement rotation/scaling
1633 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.client->origin, p);
1634 clippointtosurface(model, surface, p, out);
1635 // FIXME: implement rotation/scaling
1636 VectorAdd(out, ed->fields.client->origin, PRVM_G_VECTOR(OFS_RETURN));
1639 // #443 void(entity e, entity tagentity, string tagname) setattachment
1640 void VM_CL_setattachment (void)
1642 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
1643 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
1644 const char *tagname = PRVM_G_STRING(OFS_PARM2);
1649 if (e == prog->edicts)
1651 VM_Warning("setattachment: can not modify world entity\n");
1654 if (e->priv.server->free)
1656 VM_Warning("setattachment: can not modify free entity\n");
1660 if (tagentity == NULL)
1661 tagentity = prog->edicts;
1663 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
1665 v->edict = PRVM_EDICT_TO_PROG(tagentity);
1667 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
1670 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
1672 modelindex = (int)tagentity->fields.client->modelindex;
1673 model = CSQC_GetModelByIndex(modelindex);
1676 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.client->skin, tagname);
1678 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);
1681 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));
1685 /////////////////////////////////////////
1686 // DP_MD3_TAGINFO extension coded by VorteX
1688 int CL_GetTagIndex (prvm_edict_t *e, const char *tagname)
1690 model_t *model = CSQC_GetModelFromEntity(e);
1692 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.client->skin, tagname);
1697 // Warnings/errors code:
1698 // 0 - normal (everything all-right)
1701 // 3 - null or non-precached model
1702 // 4 - no tags with requested index
1703 // 5 - runaway loop at attachment chain
1704 extern cvar_t cl_bob;
1705 extern cvar_t cl_bobcycle;
1706 extern cvar_t cl_bobup;
1707 int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
1710 int reqframe, attachloop;
1711 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
1712 prvm_edict_t *attachent;
1715 *out = identitymatrix; // warnings and errors return identical matrix
1717 if (ent == prog->edicts)
1719 if (ent->priv.server->free)
1722 model = CSQC_GetModelFromEntity(ent);
1727 if (ent->fields.client->frame >= 0 && ent->fields.client->frame < model->numframes && model->animscenes)
1728 reqframe = model->animscenes[(int)ent->fields.client->frame].firstframe;
1730 reqframe = 0; // if model has wrong frame, engine automatically switches to model first frame
1732 // get initial tag matrix
1735 int ret = Mod_Alias_GetTagMatrix(model, reqframe, tagindex - 1, &tagmatrix);
1740 tagmatrix = identitymatrix;
1742 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
1743 { // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
1747 attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached
1748 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index);
1750 model = CSQC_GetModelFromEntity(attachent);
1752 if (model && val->_float >= 1 && model->animscenes && attachent->fields.client->frame >= 0 && attachent->fields.client->frame < model->numframes)
1753 Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->fields.client->frame].firstframe, (int)val->_float - 1, &attachmatrix);
1755 attachmatrix = identitymatrix;
1757 // apply transformation by child entity matrix
1758 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
1759 if (val->_float == 0)
1761 Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], val->_float);
1762 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
1763 Matrix4x4_Copy(&tagmatrix, out);
1765 // finally transformate by matrix of tag on parent entity
1766 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
1767 Matrix4x4_Copy(&tagmatrix, out);
1771 if (attachloop > 255) // prevent runaway looping
1774 while ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict);
1777 // normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain)
1778 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
1779 if (val->_float == 0)
1781 // Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype...
1782 Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], val->_float);
1783 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
1785 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && (RF_VIEWMODEL & (int)val->_float))
1786 {// RENDER_VIEWMODEL magic
1787 Matrix4x4_Copy(&tagmatrix, out);
1789 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
1790 if (val->_float == 0)
1793 Matrix4x4_CreateFromQuakeEntity(&entitymatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], val->_float);
1794 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
1797 // Cl_bob, ported from rendering code
1798 if (ent->fields.client->health > 0 && cl_bob.value && cl_bobcycle.value)
1801 // LordHavoc: this code is *weird*, but not replacable (I think it
1802 // should be done in QC on the server, but oh well, quake is quake)
1803 // LordHavoc: figured out bobup: the time at which the sin is at 180
1804 // degrees (which allows lengthening or squishing the peak or valley)
1805 cycle = sv.time/cl_bobcycle.value;
1806 cycle -= (int)cycle;
1807 if (cycle < cl_bobup.value)
1808 cycle = sin(M_PI * cycle / cl_bobup.value);
1810 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
1811 // bob is proportional to velocity in the xy plane
1812 // (don't count Z, or jumping messes it up)
1813 bob = sqrt(ent->fields.client->velocity[0]*ent->fields.client->velocity[0] + ent->fields.client->velocity[1]*ent->fields.client->velocity[1])*cl_bob.value;
1814 bob = bob*0.3 + bob*0.7*cycle;
1815 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
1822 // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
1823 void VM_CL_gettagindex (void)
1825 prvm_edict_t *ent = PRVM_G_EDICT(OFS_PARM0);
1826 const char *tag_name = PRVM_G_STRING(OFS_PARM1);
1827 int modelindex, tag_index;
1829 if (ent == prog->edicts)
1831 VM_Warning("gettagindex: can't affect world entity\n");
1834 if (ent->priv.server->free)
1836 VM_Warning("gettagindex: can't affect free entity\n");
1840 modelindex = (int)ent->fields.client->modelindex;
1842 modelindex = -(modelindex+1);
1844 if (modelindex <= 0 || modelindex >= MAX_MODELS)
1845 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
1848 tag_index = CL_GetTagIndex(ent, tag_name);
1850 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
1852 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
1855 // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
1856 void VM_CL_gettaginfo (void)
1858 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
1859 int tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
1860 matrix4x4_t tag_matrix;
1863 returncode = CL_GetTagMatrix(&tag_matrix, e, tagindex);
1864 Matrix4x4_ToVectors(&tag_matrix, prog->globals.client->v_forward, prog->globals.client->v_right, prog->globals.client->v_up, PRVM_G_VECTOR(OFS_RETURN));
1869 VM_Warning("gettagindex: can't affect world entity\n");
1872 VM_Warning("gettagindex: can't affect free entity\n");
1875 Con_DPrintf("CL_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
1878 Con_DPrintf("CL_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
1881 Con_DPrintf("CL_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
1886 //=================================================
1887 //[515]: here goes test/unfinished/etc.
1889 //[515]: check if it is what it should be
1890 void VM_WasFreed (void)
1893 VM_SAFEPARMCOUNT(1, VM_WasFreed);
1895 e = PRVM_G_EDICT(OFS_PARM0);
1896 if (!e->priv.required->free || (e->priv.required->free && (e->priv.required->freetime < 2 || (prog->globals.client->time - e->priv.required->freetime) > 0.5 )))
1897 PRVM_G_FLOAT(OFS_RETURN) = false;
1899 PRVM_G_FLOAT(OFS_RETURN) = true;
1902 void VM_CL_select_cube (void)
1905 float *mins2, *maxs2;
1906 prvm_edict_t *ent, *chain;
1907 vec3_t mins1, maxs1;
1909 VM_SAFEPARMCOUNT(2, VM_CL_select_cube);
1911 if (prog->fieldoffsets.chain < 0)
1912 PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
1914 chain = prog->edicts;
1916 mins2 = PRVM_G_VECTOR(OFS_PARM0);
1917 maxs2 = PRVM_G_VECTOR(OFS_PARM1);
1919 ent = PRVM_NEXT_EDICT(prog->edicts);
1920 for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
1922 if (ent->priv.required->free)
1924 VectorCopy(ent->fields.client->origin, mins1);
1925 VectorAdd(mins1, ent->fields.client->maxs, maxs1);
1926 VectorAdd(mins1, ent->fields.client->mins, mins1);
1927 if (mins1[0] > maxs2[0] || mins1[1] > maxs2[1] || mins1[2] > maxs2[2])
1929 if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2])
1931 PRVM_EDICTFIELDVALUE(ent,prog->fieldoffsets.chain)->edict = PRVM_NUM_FOR_EDICT(chain);
1935 VM_RETURN_EDICT(chain);
1938 void VM_CL_select_super (void)
1942 prvm_edict_t *ent, *chain;
1943 vec3_t mins1, maxs1;
1945 VM_SAFEPARMCOUNT(8, VM_findchain);
1947 v[i] = PRVM_G_VECTOR(OFS_PARM0+i*3);
1949 if (prog->fieldoffsets.chain < 0)
1950 PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
1952 chain = prog->edicts;
1954 mins2 = PRVM_G_VECTOR(OFS_PARM0);
1955 maxs2 = PRVM_G_VECTOR(OFS_PARM1);
1957 ent = PRVM_NEXT_EDICT(prog->edicts);
1958 for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
1960 if (ent->priv.required->free)
1962 VectorCopy(ent->fields.client->origin, mins1);
1963 VectorAdd(mins1, ent->fields.client->maxs, maxs1);
1964 VectorAdd(mins1, ent->fields.client->mins, mins1);
1965 if (mins1[0] > maxs2[0] || mins1[1] > maxs2[1] || mins1[2] > maxs2[2])
1967 if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2])
1969 PRVM_EDICTFIELDVALUE(ent,prog->fieldoffsets.chain)->edict = PRVM_NUM_FOR_EDICT(chain);
1973 VM_RETURN_EDICT(chain);*/
1976 static int Is_Text_Color (char c, char t)
1979 char c2 = c - (c & 128);
1980 char t2 = t - (t & 128);
1982 if(c != STRING_COLOR_TAG && c2 != STRING_COLOR_TAG) return 0;
1983 if(t >= '0' && t <= '9') a = 1;
1984 if(t2 >= '0' && t2 <= '9') a = 1;
1985 /* if(t >= 'A' && t <= 'Z') a = 2;
1986 if(t2 >= 'A' && t2 <= 'Z') a = 2;
1988 if(a == 1 && scr_colortext.integer > 0)
1990 if(a == 2 && scr_multifonts.integer > 0)
1996 void VM_uncolorstring (void) //#170
1999 char out[VM_STRINGTEMP_LENGTH];
2002 VM_SAFEPARMCOUNT(1, VM_uncolorstring);
2003 in = PRVM_G_STRING(OFS_PARM0);
2004 VM_CheckEmptyString (in);
2009 if(Is_Text_Color(in[k], in[k+1]) == 1/* || (in[k] == '&' && in[k+1] == 'r')*/)
2018 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(out);
2021 void VM_CL_selecttraceline (void)
2024 int ent, ignore, csqcents;
2026 v1 = PRVM_G_VECTOR(OFS_PARM0);
2027 v2 = PRVM_G_VECTOR(OFS_PARM1);
2028 ignore = (int)PRVM_G_FLOAT(OFS_PARM2);
2029 csqcents = (int)PRVM_G_FLOAT(OFS_PARM3);
2034 VM_Warning("VM_CL_selecttraceline: csqcents flag not supported anymore, and this function is deprecated\n");
2037 prog->globals.client->trace_fraction = CL_SelectTraceLine(v1, v2, prog->globals.client->trace_endpos, prog->globals.client->trace_plane_normal, &ent, &cl.entities[ignore].render);
2038 PRVM_G_FLOAT(OFS_RETURN) = ent;
2041 void VM_charindex (void)
2044 s = PRVM_G_STRING(OFS_PARM0);
2045 if((unsigned)PRVM_G_FLOAT(OFS_PARM1) > strlen(s))
2047 PRVM_G_FLOAT(OFS_RETURN) = (unsigned char)s[(int)PRVM_G_FLOAT(OFS_PARM1)];
2050 //#223 string(float c, ...) chr2str (FTE_STRINGS)
2051 void VM_chr2str (void)
2055 for(i = 0;i < prog->argc && i < (int)sizeof(t) - 1;i++)
2056 t[i] = (unsigned char)PRVM_G_FLOAT(OFS_PARM0+i*3);
2058 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
2061 //#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2062 void VM_strncmp (void)
2064 const char *s1, *s2;
2065 VM_SAFEPARMCOUNT(1, VM_strncmp);
2066 s1 = PRVM_G_STRING(OFS_PARM0);
2067 s2 = PRVM_G_STRING(OFS_PARM1);
2068 PRVM_G_FLOAT(OFS_RETURN) = strncmp(s1, s2, (size_t)PRVM_G_FLOAT(OFS_PARM2));
2071 //============================================================================
2072 //============================================================================
2074 prvm_builtin_t vm_cl_builtins[] = {
2075 0, // to be consistent with the old vm
2076 VM_CL_makevectors, // #1 void(vector ang) makevectors
2077 VM_CL_setorigin, // #2 void(entity e, vector o) setorigin
2078 VM_CL_setmodel, // #3 void(entity e, string m) setmodel
2079 VM_CL_setsize, // #4 void(entity e, vector min, vector max) setsize
2081 VM_break, // #6 void() break
2082 VM_random, // #7 float() random
2083 VM_CL_sound, // #8 void(entity e, float chan, string samp) sound
2084 VM_normalize, // #9 vector(vector v) normalize
2085 VM_error, // #10 void(string e) error
2086 VM_objerror, // #11 void(string e) objerror
2087 VM_vlen, // #12 float(vector v) vlen
2088 VM_vectoyaw, // #13 float(vector v) vectoyaw
2089 VM_CL_spawn, // #14 entity() spawn
2090 VM_remove, // #15 void(entity e) remove
2091 VM_CL_traceline, // #16 float(vector v1, vector v2, float tryents) traceline
2093 VM_find, // #18 entity(entity start, .string fld, string match) find
2094 VM_CL_precache_sound, // #19 void(string s) precache_sound
2095 VM_CL_precache_model, // #20 void(string s) precache_model
2097 VM_CL_findradius, // #22 entity(vector org, float rad) findradius
2100 VM_dprint, // #25 void(string s) dprint
2101 VM_ftos, // #26 void(string s) ftos
2102 VM_vtos, // #27 void(string s) vtos
2103 VM_coredump, // #28 void() coredump
2104 VM_traceon, // #29 void() traceon
2105 VM_traceoff, // #30 void() traceoff
2106 VM_eprint, // #31 void(entity e) eprint
2109 VM_CL_droptofloor, // #34 float() droptofloor
2110 VM_CL_lightstyle, // #35 void(float style, string value) lightstyle
2111 VM_rint, // #36 float(float v) rint
2112 VM_floor, // #37 float(float v) floor
2113 VM_ceil, // #38 float(float v) ceil
2115 VM_CL_checkbottom, // #40 float(entity e) checkbottom
2116 VM_CL_pointcontents, // #41 float(vector v) pointcontents
2118 VM_fabs, // #43 float(float f) fabs
2120 VM_cvar, // #45 float(string s) cvar
2121 VM_localcmd, // #46 void(string s) localcmd
2122 VM_nextent, // #47 entity(entity e) nextent
2123 VM_CL_particle, // #48 void(vector o, vector d, float color, float count) particle
2124 VM_changeyaw, // #49 void(entity ent) ChangeYaw
2126 VM_vectoangles, // #51 vector(vector v) vectoangles
2127 0, // #52 void(float to, float f) WriteByte
2128 0, // #53 void(float to, float f) WriteChar
2129 0, // #54 void(float to, float f) WriteShort
2130 0, // #55 void(float to, float f) WriteLong
2131 0, // #56 void(float to, float f) WriteCoord
2132 0, // #57 void(float to, float f) WriteAngle
2133 0, // #58 void(float to, string s) WriteString
2135 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
2136 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
2137 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
2138 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
2139 VM_CL_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
2140 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS)
2147 VM_cvar_set, // #72 void(string var, string val) cvar_set
2149 VM_CL_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound
2150 VM_CL_precache_model, // #75 string(string s) precache_model2
2151 VM_CL_precache_sound, // #76 string(string s) precache_sound2
2156 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2165 VM_CL_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2166 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2167 VM_CL_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2168 PF_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2169 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2170 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2171 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2172 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2173 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2174 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2185 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2186 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2187 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2188 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2189 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2190 VM_strcat, // #115 string(string s1, string s2) strcat (FRIK_FILE)
2191 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2192 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2193 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2194 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2196 e10, e10, e10, e10, e10, e10, e10, e10, // #120-199
2206 VM_bitshift, //#218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2210 VM_charindex, //#222 float(string str, float ofs) str2chr (FTE_STRINGS)
2211 VM_chr2str, //#223 string(float c, ...) chr2str (FTE_STRINGS)
2216 VM_strncmp, //#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2218 e10, e10, e10, e10, e10, e10, e10, // #230-299
2220 //======CSQC start=======//
2221 //3d world (buffer/buffering) operations
2222 VM_R_ClearScene, //#300 void() clearscene (EXT_CSQC)
2223 VM_R_AddEntities, //#301 void(float mask) addentities (EXT_CSQC)
2224 VM_R_AddEntity, //#302 void(entity ent) addentity (EXT_CSQC)
2225 VM_R_SetView, //#303 float(float property, ...) setproperty (EXT_CSQC)
2226 VM_R_RenderScene, //#304 void() renderscene (EXT_CSQC)
2227 VM_R_AddDynamicLight, //#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2228 VM_R_PolygonBegin, //#306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2229 VM_R_PolygonVertex, //#307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2230 VM_R_PolygonEnd, //#308 void() R_EndPolygon
2233 //maths stuff that uses the current view settings
2234 VM_CL_unproject, //#310 vector (vector v) cs_unproject (EXT_CSQC)
2235 VM_CL_project, //#311 vector (vector v) cs_project (EXT_CSQC)
2240 //2d (immediate) operations
2241 VM_drawline, //#315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2242 VM_iscachedpic, //#316 float(string name) iscachedpic (EXT_CSQC)
2243 VM_precache_pic, //#317 string(string name, float trywad) precache_pic (EXT_CSQC)
2244 VM_getimagesize, //#318 vector(string picname) draw_getimagesize (EXT_CSQC)
2245 VM_freepic, //#319 void(string name) freepic (EXT_CSQC)
2246 VM_drawcharacter, //#320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2247 VM_drawstring, //#321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2248 VM_drawpic, //#322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2249 VM_drawfill, //#323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2250 VM_drawsetcliparea, //#324 void(float x, float y, float width, float height) drawsetcliparea
2251 VM_drawresetcliparea, //#325 void(void) drawresetcliparea
2257 VM_CL_getstatf, //#330 float(float stnum) getstatf (EXT_CSQC)
2258 VM_CL_getstati, //#331 float(float stnum) getstati (EXT_CSQC)
2259 VM_CL_getstats, //#332 string(float firststnum) getstats (EXT_CSQC)
2260 VM_CL_setmodelindex, //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2261 VM_CL_modelnameforindex, //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2262 VM_CL_particleeffectnum, //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2263 VM_CL_trailparticles, //#336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2264 VM_CL_pointparticles, //#337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
2265 VM_CL_centerprint, //#338 void(string s) cprint (EXT_CSQC)
2266 VM_print, //#339 void(string s) print (EXT_CSQC)
2267 VM_keynumtostring, //#340 string(float keynum) keynumtostring (EXT_CSQC)
2268 VM_stringtokeynum, //#341 float(string keyname) stringtokeynum (EXT_CSQC)
2269 VM_CL_getkeybind, //#342 string(float keynum) getkeybind (EXT_CSQC)
2270 VM_CL_setcursormode, //#343 void(float usecursor) setcursormode (EXT_CSQC)
2271 VM_getmousepos, //#344 vector() getmousepos (EXT_CSQC)
2272 VM_CL_getinputstate, //#345 float(float framenum) getinputstate (EXT_CSQC)
2273 VM_CL_setsensitivityscale, //#346 void(float sens) setsensitivityscaler (EXT_CSQC)
2274 VM_CL_runplayerphysics, //#347 void() runstandardplayerphysics (EXT_CSQC)
2275 VM_CL_getplayerkey, //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
2276 VM_CL_isdemo, //#349 float() isdemo (EXT_CSQC)
2277 VM_isserver, //#350 float() isserver (EXT_CSQC)
2278 VM_CL_setlistener, //#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
2279 VM_CL_registercmd, //#352 void(string cmdname) registercommand (EXT_CSQC)
2280 VM_WasFreed, //#353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
2281 VM_CL_playernum, //#354 float() playernum
2282 VM_CL_onground, //#355 float() cl_onground (EXT_CSQC)
2283 VM_charindex, //#356 float(string s, float num) charindex
2284 VM_CL_selecttraceline, //#357 float(vector start, vector end, float ignore, float csqcents) selecttraceline
2287 VM_CL_ReadByte, //#360 float() readbyte (EXT_CSQC)
2288 VM_CL_ReadChar, //#361 float() readchar (EXT_CSQC)
2289 VM_CL_ReadShort, //#362 float() readshort (EXT_CSQC)
2290 VM_CL_ReadLong, //#363 float() readlong (EXT_CSQC)
2291 VM_CL_ReadCoord, //#364 float() readcoord (EXT_CSQC)
2292 VM_CL_ReadAngle, //#365 float() readangle (EXT_CSQC)
2293 VM_CL_ReadString, //#366 string() readstring (EXT_CSQC)
2294 VM_CL_ReadFloat, //#367 float() readfloat (EXT_CSQC)
2327 //=========CSQC end========//
2329 VM_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
2331 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
2332 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
2333 VM_CL_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
2334 VM_CL_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
2335 VM_CL_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
2336 VM_CL_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
2337 VM_CL_te_particlecube, // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
2338 VM_CL_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
2339 VM_CL_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
2340 VM_CL_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
2341 VM_CL_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
2342 VM_CL_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
2343 VM_CL_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
2344 VM_CL_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
2345 VM_CL_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
2346 VM_CL_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
2347 VM_CL_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
2348 VM_CL_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
2349 VM_CL_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
2350 VM_CL_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
2351 VM_CL_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
2352 VM_CL_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
2353 VM_CL_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
2354 VM_CL_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
2355 VM_CL_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
2356 VM_CL_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
2357 VM_CL_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
2358 VM_CL_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
2359 VM_CL_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
2360 VM_CL_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
2361 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
2362 VM_CL_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
2363 VM_CL_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
2364 VM_CL_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
2365 VM_CL_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
2366 VM_CL_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
2367 VM_CL_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
2368 VM_CL_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
2370 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
2371 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
2372 VM_CL_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
2373 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
2374 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
2375 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
2376 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
2377 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
2378 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
2379 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
2380 VM_CL_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
2381 VM_CL_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
2389 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
2390 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
2391 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
2392 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
2393 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
2394 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
2395 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
2396 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
2397 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
2398 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
2400 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
2401 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
2402 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
2403 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
2404 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
2405 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
2406 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
2407 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
2409 e10, e10 // #480-499 (LordHavoc)
2412 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
2414 void VM_CL_Cmd_Init(void)
2418 void VM_CL_Cmd_Reset(void)