#include "prvm_cmds.h"
#include "csprogs.h"
#include "cl_collision.h"
+#include "r_shadow.h"
//============================================================================
// Client
//[515]: unsolved PROBLEMS
//- finish player physics code (cs_runplayerphysics)
-//- fix R_AddDynamicLight
//- EntWasFreed ?
//- RF_DEPTHHACK is not like it should be
//- add builtin that sets cl.viewangles instead of reading "input_angles" global
//[515]: really need new list ?
char *vm_cl_extensions =
+"BX_WAL_SUPPORT "
"DP_CON_SET "
"DP_CON_SETA "
"DP_CON_STARTMAP "
"DP_MONSTERWALK "
"DP_MOVETYPEBOUNCEMISSILE "
"DP_MOVETYPEFOLLOW "
+"DP_QC_ASINACOSATANATAN2TAN "
"DP_QC_CHANGEPITCH "
"DP_QC_COPYENTITY "
"DP_QC_CVAR_STRING "
"DP_QC_RANDOMVEC "
"DP_QC_SINCOSSQRTPOW "
//"DP_QC_STRINGBUFFERS " //[515]: not needed ?
+"DP_QC_STRFTIME "
+"DP_QC_STRINGCOLORFUNCTIONS "
"DP_QC_TRACEBOX "
//"DP_QC_TRACETOSS "
"DP_QC_TRACE_MOVETYPE_HITMODEL "
"DP_QC_TRACE_MOVETYPE_WORLDONLY "
+"DP_QC_UNLIMITEDTEMPSTRINGS "
"DP_QC_VECTORVECTORS "
"DP_QUAKE2_MODEL "
"DP_QUAKE2_SPRITE "
int Sbar_GetPlayer (int index);
void Sbar_SortFrags (void);
void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
-void CL_ExpandCSQCEntities(int num);
void CSQC_RelinkAllEntities (int drawmask);
void CSQC_RelinkCSQCEntities (void);
char *Key_GetBind (int key);
+model_t *CSQC_GetModelByIndex(int modelindex);
+model_t *CSQC_GetModelFromEntity(prvm_edict_t *ed);
+void CL_LinkEdict(prvm_edict_t *ed);
+
}
org = PRVM_G_VECTOR(OFS_PARM1);
VectorCopy (org, e->fields.client->origin);
+ CL_LinkEdict(e);
}
// #3 void(entity e, string m) setmodel
e = PRVM_G_EDICT(OFS_PARM0);
m = PRVM_G_STRING(OFS_PARM1);
- for(i=0;i<MAX_MODELS;i++)
- if(!cl.csqc_model_precache[i])
- break;
- else
- if(!strcmp(cl.csqc_model_precache[i]->name, m))
+ for (i = 0;i < MAX_MODELS && cl.csqc_model_precache[i];i++)
+ {
+ if (!strcmp(cl.csqc_model_precache[i]->name, m))
{
e->fields.client->model = PRVM_SetEngineString(cl.csqc_model_precache[i]->name);
e->fields.client->modelindex = -(i+1);
return;
}
+ }
- for (i=0, mod = cl.model_precache[0] ; i < MAX_MODELS ; i++, mod = cl.model_precache[i])
- if(mod)
- if(!strcmp(mod->name, m))
+ for (i = 0;i < MAX_MODELS;i++)
+ {
+ mod = cl.model_precache[i];
+ if (mod && !strcmp(mod->name, m))
{
e->fields.client->model = PRVM_SetEngineString(mod->name);
e->fields.client->modelindex = i;
return;
}
+ }
+
e->fields.client->modelindex = 0;
e->fields.client->model = 0;
}
VectorCopy (min, e->fields.client->mins);
VectorCopy (max, e->fields.client->maxs);
VectorSubtract (max, min, e->fields.client->size);
+
+ CL_LinkEdict(e);
}
// #8 void(entity e, float chan, string samp) sound
// #19 void(string s) precache_sound
void VM_CL_precache_sound (void)
{
- const char *n;
VM_SAFEPARMCOUNT(1, VM_CL_precache_sound);
- n = PRVM_G_STRING(OFS_PARM0);
- S_PrecacheSound(n, true, false);
+ S_PrecacheSound(PRVM_G_STRING(OFS_PARM0), true, false);
}
// #20 void(string s) precache_model
VM_SAFEPARMCOUNT(1, VM_CL_precache_model);
name = PRVM_G_STRING(OFS_PARM0);
- for(i=1;i<MAX_MODELS;i++)
- if(!cl.csqc_model_precache[i])
- {
- i = 0;
- break;
- }
- else
+ for (i = 1;i < MAX_MODELS && cl.csqc_model_precache[i];i++)
+ {
if(!strcmp(cl.csqc_model_precache[i]->name, name))
{
- i = -(i+1);
- break;
+ PRVM_G_FLOAT(OFS_RETURN) = -(i+1);
+ return;
}
- if(i)
- {
- PRVM_G_FLOAT(OFS_RETURN) = i;
- return;
}
PRVM_G_FLOAT(OFS_RETURN) = 0;
m = Mod_ForName(name, false, false, false);
if(m && m->loaded)
{
- for(i=1;i<MAX_MODELS;i++)
- if(!cl.csqc_model_precache[i])
- break;
- if(i == MAX_MODELS)
+ for (i = 1;i < MAX_MODELS;i++)
{
- VM_Warning("VM_CL_precache_model: no free models\n");
- return;
+ if (!cl.csqc_model_precache[i])
+ {
+ cl.csqc_model_precache[i] = (model_t*)m;
+ PRVM_G_FLOAT(OFS_RETURN) = -(i+1);
+ return;
+ }
}
- cl.csqc_model_precache[i] = (model_t*)m;
- PRVM_G_FLOAT(OFS_RETURN) = -(i+1);
+ VM_Warning("VM_CL_precache_model: no free models\n");
return;
}
VM_Warning("VM_CL_precache_model: model \"%s\" not found\n", name);
CL_ParticleEffect(EFFECT_SVC_PARTICLE, count, org, org, dir, dir, NULL, color);
}
-// #49 void(entity ent, float ideal_yaw, float speed_yaw) ChangeYaw
-void VM_CL_changeyaw (void)
-{
- prvm_edict_t *ent;
- float ideal, current, move, speed;
- VM_SAFEPARMCOUNT(3, VM_CL_changeyaw);
-
- ent = PRVM_G_EDICT(OFS_PARM0);
- if (ent == prog->edicts)
- {
- VM_Warning("changeyaw: can not modify world entity\n");
- return;
- }
- if (ent->priv.server->free)
- {
- VM_Warning("changeyaw: can not modify free entity\n");
- return;
- }
- current = ANGLEMOD(ent->fields.client->angles[1]);
- ideal = PRVM_G_FLOAT(OFS_PARM1);
- speed = PRVM_G_FLOAT(OFS_PARM2);
-
- if (current == ideal)
- return;
- move = ideal - current;
- if (ideal > current)
- {
- if (move >= 180)
- move = move - 360;
- }
- else
- {
- if (move <= -180)
- move = move + 360;
- }
- if (move > 0)
- {
- if (move > speed)
- move = speed;
- }
- else
- {
- if (move < -speed)
- move = -speed;
- }
-
- ent->fields.client->angles[1] = ANGLEMOD (current + move);
-}
-
-// #63 void(entity ent, float ideal_pitch, float speed_pitch) changepitch (DP_QC_CHANGEPITCH)
-void VM_CL_changepitch (void)
-{
- prvm_edict_t *ent;
- float ideal, current, move, speed;
- VM_SAFEPARMCOUNT(3, VM_CL_changepitch);
-
- ent = PRVM_G_EDICT(OFS_PARM0);
- if (ent == prog->edicts)
- {
- VM_Warning("changepitch: can not modify world entity\n");
- return;
- }
- if (ent->priv.server->free)
- {
- VM_Warning("changepitch: can not modify free entity\n");
- return;
- }
- current = ANGLEMOD( ent->fields.client->angles[0] );
- ideal = PRVM_G_FLOAT(OFS_PARM1);
- speed = PRVM_G_FLOAT(OFS_PARM2);
-
- if (current == ideal)
- return;
- move = ideal - current;
- if (ideal > current)
- {
- if (move >= 180)
- move = move - 360;
- }
- else
- {
- if (move <= -180)
- move = move + 360;
- }
- if (move > 0)
- {
- if (move > speed)
- move = speed;
- }
- else
- {
- if (move < -speed)
- move = -speed;
- }
-
- ent->fields.client->angles[0] = ANGLEMOD (current + move);
-}
-
// #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
void VM_CL_tracetoss (void)
{
//============================================================================
//[515]: SCENE MANAGER builtins
-extern void V_CalcRefdef (void);//view.c
extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed);//csprogs.c
-extern void CSQC_ClearCSQCEntities (void);//csprogs.c
matrix4x4_t csqc_listenermatrix;
-qboolean csqc_usecsqclistener = false, csqc_frame = false;//[515]: per-frame
+qboolean csqc_usecsqclistener = false;//[515]: per-frame
static void CSQC_R_RecalcView (void)
{
extern matrix4x4_t viewmodelmatrix;
- viewmodelmatrix = identitymatrix;
- r_view.matrix = identitymatrix;
Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 1);
- Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 0.3);
+ 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);
}
+void CL_RelinkLightFlashes(void);
//#300 void() clearscene (EXT_CSQC)
void VM_R_ClearScene (void)
{
VM_SAFEPARMCOUNT(0, VM_R_ClearScene);
-// CSQC_R_RecalcView();
- CSQC_ClearCSQCEntities();
+ // clear renderable entity and light lists
+ r_refdef.numentities = 0;
+ r_refdef.numlights = 0;
}
//#301 void(float mask) addentities (EXT_CSQC)
VM_SAFEPARMCOUNT(1, VM_R_AddEntities);
drawmask = (int)PRVM_G_FLOAT(OFS_PARM0);
CSQC_RelinkAllEntities(drawmask);
+ CL_RelinkLightFlashes();
- *prog->time = cl.time;
+ prog->globals.client->time = cl.time;
for(i=1;i<prog->num_edicts;i++)
{
ed = &prog->edicts[i];
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
+extern void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit);
//#304 void() renderscene (EXT_CSQC)
void VM_R_RenderScene (void) //#134
{
+ int i;
VM_SAFEPARMCOUNT(0, VM_R_RenderScene);
+ // we need to update any RENDER_VIEWMODEL entities at this point because
+ // csqc supplies its own view matrix
+ for (i = 1;i < cl.num_entities;i++)
+ {
+ if (cl.entities_active[i])
+ {
+ entity_t *ent = cl.entities + i;
+ if ((ent->render.flags & RENDER_VIEWMODEL) || ent->state_current.tagentity)
+ CL_UpdateNetworkEntity(ent, 32);
+ }
+ }
+ // and of course the engine viewmodel needs updating as well
+ CL_UpdateNetworkEntity(&cl.viewent, 32);
+ // now draw stuff!
R_RenderView();
}
void VM_R_AddDynamicLight (void)
{
float *pos, *col;
- matrix4x4_t tempmatrix;
+ matrix4x4_t matrix;
VM_SAFEPARMCOUNT(3, VM_R_AddDynamicLight);
+ // if we've run out of dlights, just return
+ if (r_refdef.numlights >= MAX_DLIGHTS)
+ return;
+
pos = PRVM_G_VECTOR(OFS_PARM0);
col = PRVM_G_VECTOR(OFS_PARM2);
- Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
- CL_AllocDlight(NULL, &tempmatrix, PRVM_G_FLOAT(OFS_PARM1), col[0], col[1], col[2], 500, 0, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
- //CL_AllocDlight(NULL, &tempmatrix, PRVM_G_FLOAT(OFS_PARM1), col[0], col[1], col[2], 500, 0.2, 0, -1, true, 1, 0.25, 1, 0, 0, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+ Matrix4x4_CreateFromQuakeEntity(&matrix, pos[0], pos[1], pos[2], 0, 0, 0, PRVM_G_FLOAT(OFS_PARM1));
+ 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);
}
//============================================================================
void VM_CL_getstats (void)
{
int i;
- char *t;
+ char t[17];
VM_SAFEPARMCOUNT(1, VM_CL_getstats);
i = (int)PRVM_G_FLOAT(OFS_PARM0);
if(i < 0 || i > MAX_CL_STATS-4)
{
+ PRVM_G_INT(OFS_RETURN) = OFS_NULL;
VM_Warning("VM_CL_getstats: index>MAX_CL_STATS-4 or index<0\n");
return;
}
- t = VM_GetTempString();
- strlcpy(t, (char*)&cl.stats[i], 16);
- PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(t);
+ strlcpy(t, (char*)&cl.stats[i], sizeof(t));
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
}
//#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
{
int i;
prvm_edict_t *t;
- struct model_s *m;
+ struct model_s *model;
VM_SAFEPARMCOUNT(2, VM_CL_setmodelindex);
t = PRVM_G_EDICT(OFS_PARM0);
+
i = (int)PRVM_G_FLOAT(OFS_PARM1);
t->fields.client->model = 0;
t->fields.client->modelindex = 0;
- if(!i)
+ if (!i)
return;
- if(i<0)
- {
- i = -(i+1);
- if(i >= MAX_MODELS)
- {
- VM_Warning("VM_CL_setmodelindex >= MAX_MODELS\n");
- return;
- }
- m = cl.csqc_model_precache[i];
- }
- else
- if(i >= MAX_MODELS)
- {
- VM_Warning("VM_CL_setmodelindex >= MAX_MODELS\n");
- return;
- }
- else
- m = cl.model_precache[i];
- if(!m)
+
+ model = CSQC_GetModelByIndex(i);
+ if (!model)
{
VM_Warning("VM_CL_setmodelindex: null model\n");
return;
}
- t->fields.client->model = PRVM_SetEngineString(m->name);
+ t->fields.client->model = PRVM_SetEngineString(model->name);
t->fields.client->modelindex = i;
}
//#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
void VM_CL_modelnameforindex (void)
{
- int i;
+ model_t *model;
VM_SAFEPARMCOUNT(1, VM_CL_modelnameforindex);
- PRVM_G_INT(OFS_RETURN) = 0;
- i = (int)PRVM_G_FLOAT(OFS_PARM0);
- if(i<0)
- {
- i = -(i+1);
- if(i >= MAX_MODELS)
- {
- VM_Warning("VM_CL_modelnameforindex >= MAX_MODELS\n");
- return;
- }
- if(cl.csqc_model_precache[i])
- PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(cl.csqc_model_precache[i]->name);
- return;
- }
- if(i >= MAX_MODELS)
- {
- VM_Warning("VM_CL_modelnameforindex >= MAX_MODELS\n");
- return;
- }
- if(cl.model_precache[i])
- PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(cl.model_precache[i]->name);
+ PRVM_G_INT(OFS_RETURN) = OFS_NULL;
+ model = CSQC_GetModelByIndex((int)PRVM_G_FLOAT(OFS_PARM0));
+ PRVM_G_INT(OFS_RETURN) = model ? PRVM_SetEngineString(model->name) : 0;
}
//#335 float(string effectname) particleeffectnum (EXT_CSQC)
void VM_CL_particleeffectnum (void)
{
- const char *n;
int i;
VM_SAFEPARMCOUNT(1, VM_CL_particleeffectnum);
- n = PRVM_G_STRING(OFS_PARM0);
- i = CL_ParticleEffectIndexForName(n);
+ i = CL_ParticleEffectIndexForName(PRVM_G_STRING(OFS_PARM0));
if (i == 0)
i = -1;
PRVM_G_FLOAT(OFS_RETURN) = i;
// #336 void(entity ent, float effectnum, vector start, vector end[, float color]) trailparticles (EXT_CSQC)
void VM_CL_trailparticles (void)
{
- int i, entnum;
+ int i;
float *start, *end;
prvm_edict_t *t;
VM_SAFEPARMCOUNT(4, VM_CL_trailparticles);
t = PRVM_G_EDICT(OFS_PARM0);
- entnum = PRVM_NUM_FOR_EDICT(t);
i = (int)PRVM_G_FLOAT(OFS_PARM1);
start = PRVM_G_VECTOR(OFS_PARM2);
end = PRVM_G_VECTOR(OFS_PARM3);
- if (entnum >= MAX_EDICTS)
- {
- VM_Warning("CSQC_ParseBeam: invalid entity number %i\n", entnum);
- return;
- }
- if (entnum >= cl.max_csqcentities)
- CL_ExpandCSQCEntities(entnum);
-
- CL_ParticleEffect(i, VectorDistance(start, end), start, end, t->fields.client->velocity, t->fields.client->velocity, &cl.csqcentities[entnum], (int)PRVM_G_FLOAT(OFS_PARM4));
+ CL_ParticleEffect(i, VectorDistance(start, end), start, end, t->fields.client->velocity, t->fields.client->velocity, NULL, (int)PRVM_G_FLOAT(OFS_PARM4));
}
//#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
//#342 string(float keynum) getkeybind (EXT_CSQC)
void VM_CL_getkeybind (void)
{
- int i;
-
VM_SAFEPARMCOUNT(1, VM_CL_getkeybind);
- i = (int)PRVM_G_FLOAT(OFS_PARM0);
- PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(Key_GetBind(i));
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0)));
}
//#343 void(float usecursor) setcursormode (EXT_CSQC)
int i;
char t[128];
const char *c;
- char *temp;
VM_SAFEPARMCOUNT(2, VM_CL_getplayerkey);
else
if(!strcasecmp(c, "frags"))
sprintf(t, "%i", cl.scores[i].frags);
-// else
-// if(!strcasecmp(c, "ping"))
-// sprintf(t, "%i", cl.scores[i].ping);
-// else
-// if(!strcasecmp(c, "entertime"))
-// sprintf(t, "%f", cl.scores[i].entertime);
+ else
+ if(!strcasecmp(c, "ping"))
+ sprintf(t, "%i", cl.scores[i].qw_ping);
+ else
+ if(!strcasecmp(c, "entertime"))
+ sprintf(t, "%f", cl.scores[i].qw_entertime);
else
if(!strcasecmp(c, "colors"))
sprintf(t, "%i", cl.scores[i].colors);
sprintf(t, "%i", i+1);
if(!t[0])
return;
- temp = VM_GetTempString();
- strlcpy(temp, t, VM_STRINGTEMP_LENGTH);
- PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(temp);
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
}
//#349 float() isdemo (EXT_CSQC)
//#366 string() readstring (EXT_CSQC)
void VM_CL_ReadString (void)
{
- char *t, *s;
- t = VM_GetTempString();
- s = MSG_ReadString();
- PRVM_G_INT(OFS_RETURN) = 0;
- if(s)
- {
- strlcpy(t, s, VM_STRINGTEMP_LENGTH);
- PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(t);
- }
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(MSG_ReadString());
}
//#367 float() readfloat (EXT_CSQC)
CL_FindNonSolidLocation(pos, pos2, 10);
CL_ParticleExplosion(pos2);
Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
- CL_AllocDlight(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);
+ 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);
}
// #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
pos = PRVM_G_VECTOR(OFS_PARM0);
CL_FindNonSolidLocation(pos, pos2, 4);
Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
- CL_AllocDlight(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);
+ 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);
}
// #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
color[1] = tempcolor[1] * (2.0f / 255.0f);
color[2] = tempcolor[2] * (2.0f / 255.0f);
Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
- CL_AllocDlight(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);
+ 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);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
}
//DP_QC_GETSURFACE
extern void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out);
-static model_t *cl_getmodel(prvm_edict_t *ed)
-{
- int modelindex;
- model_t *model = NULL;
- if (!ed || ed->priv.server->free)
- return NULL;
- modelindex = (int)ed->fields.client->modelindex;
- if(!modelindex)
- return NULL;
- if(modelindex<0)
- {
- modelindex = -(modelindex+1);
- if(modelindex < MAX_MODELS)
- model = cl.csqc_model_precache[modelindex];
- }
- else
- {
- if(modelindex < MAX_MODELS)
- model = cl.model_precache[modelindex];
- }
- return model;
-}
static msurface_t *cl_getsurface(model_t *model, int surfacenum)
{
// #434 float(entity e, float s) getsurfacenumpoints
void VM_CL_getsurfacenumpoints(void)
{
- model_t *model = cl_getmodel(PRVM_G_EDICT(OFS_PARM0));
+ model_t *model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0));
msurface_t *surface;
// return 0 if no such surface
if (!model || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
int pointnum;
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
ed = PRVM_G_EDICT(OFS_PARM0);
- if (!(model = cl_getmodel(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
// note: this (incorrectly) assumes it is a simple polygon
pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
msurface_t *surface;
vec3_t normal;
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
- if (!(model = cl_getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
// FIXME: implement rotation/scaling
// note: this (incorrectly) assumes it is a simple polygon
{
model_t *model;
msurface_t *surface;
- PRVM_G_INT(OFS_RETURN) = 0;
- if (!(model = cl_getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ PRVM_G_INT(OFS_RETURN) = OFS_NULL;
+ if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
- PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(surface->texture->name);
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
}
// #438 float(entity e, vector p) getsurfacenearpoint
vec_t *point;
PRVM_G_FLOAT(OFS_RETURN) = -1;
ed = PRVM_G_EDICT(OFS_PARM0);
- if(!(model = cl_getmodel(ed)) || !model->num_surfaces)
+ if(!(model = CSQC_GetModelFromEntity(ed)) || !model->num_surfaces)
return;
// FIXME: implement rotation/scaling
vec3_t p, out;
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
ed = PRVM_G_EDICT(OFS_PARM0);
- if (!(model = cl_getmodel(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
// FIXME: implement rotation/scaling
VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.client->origin, p);
if (tagentity == NULL)
tagentity = prog->edicts;
- v = PRVM_GETEDICTFIELDVALUE(e, csqc_fieldoff_tag_entity);
+ v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
if (v)
v->edict = PRVM_EDICT_TO_PROG(tagentity);
- v = PRVM_GETEDICTFIELDVALUE(e, csqc_fieldoff_tag_index);
+ v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
if (v)
v->_float = 0;
if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
{
modelindex = (int)tagentity->fields.client->modelindex;
- model = NULL;
-
- if(modelindex)
- {
- if(modelindex<0)
- {
- modelindex = -(modelindex+1);
- if(modelindex < MAX_MODELS)
- model = cl.csqc_model_precache[modelindex];
- }
- else
- if(modelindex < MAX_MODELS)
- model = cl.model_precache[modelindex];
- }
-
+ model = CSQC_GetModelByIndex(modelindex);
if (model)
{
v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.client->skin, tagname);
int CL_GetTagIndex (prvm_edict_t *e, const char *tagname)
{
- int i;
- model_t *m;
-
- i = (int)e->fields.client->modelindex;
-
- if(!i)
- return -1;
- if(i<0)
- {
- i = -(i+1);
- if(i >= MAX_MODELS)
- return -1;
- m = cl.csqc_model_precache[i];
- }
+ model_t *model = CSQC_GetModelFromEntity(e);
+ if (model)
+ return Mod_Alias_GetTagIndexForName(model, (int)e->fields.client->skin, tagname);
else
- if(i >= MAX_MODELS)
- return -1;
- else
- m = cl.model_precache[i];
-
- return Mod_Alias_GetTagIndexForName(m, (int)e->fields.client->skin, tagname);
+ return -1;
};
// Warnings/errors code:
int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
{
prvm_eval_t *val;
- int modelindex, reqframe, attachloop, i;
+ int reqframe, attachloop;
matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
prvm_edict_t *attachent;
model_t *model;
if (ent->priv.server->free)
return 2;
- modelindex = (int)ent->fields.client->modelindex;
+ model = CSQC_GetModelFromEntity(ent);
- if(!modelindex)
+ if(!model)
return 3;
- if(modelindex<0)
- {
- modelindex = -(modelindex+1);
- if(modelindex >= MAX_MODELS)
- return 3;
- model = cl.csqc_model_precache[modelindex];
- }
- else
- if(modelindex >= MAX_MODELS)
- return 3;
- else
- model = cl.model_precache[modelindex];
if (ent->fields.client->frame >= 0 && ent->fields.client->frame < model->numframes && model->animscenes)
reqframe = model->animscenes[(int)ent->fields.client->frame].firstframe;
else
tagmatrix = identitymatrix;
- if ((val = PRVM_GETEDICTFIELDVALUE(ent, csqc_fieldoff_tag_entity)) && val->edict)
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
{ // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
attachloop = 0;
do
{
attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached
- val = PRVM_GETEDICTFIELDVALUE(ent, csqc_fieldoff_tag_index);
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index);
- model = NULL;
- i = (int)attachent->fields.client->modelindex;
- if(i<0)
- {
- i = -(i+1);
- if(i < MAX_MODELS)
- model = cl.csqc_model_precache[i];
- }
- else
- if(i < MAX_MODELS)
- model = cl.model_precache[i];
+ model = CSQC_GetModelFromEntity(attachent);
if (model && val->_float >= 1 && model->animscenes && attachent->fields.client->frame >= 0 && attachent->fields.client->frame < model->numframes)
Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->fields.client->frame].firstframe, (int)val->_float - 1, &attachmatrix);
attachmatrix = identitymatrix;
// apply transformation by child entity matrix
- val = PRVM_GETEDICTFIELDVALUE(ent, csqc_fieldoff_scale);
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
if (val->_float == 0)
val->_float = 1;
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);
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
- out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
- out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
- out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
Matrix4x4_Copy(&tagmatrix, out);
// finally transformate by matrix of tag on parent entity
Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
- out->m[0][3] = attachmatrix.m[0][3] + attachmatrix.m[0][0]*tagmatrix.m[0][3] + attachmatrix.m[0][1]*tagmatrix.m[1][3] + attachmatrix.m[0][2]*tagmatrix.m[2][3];
- out->m[1][3] = attachmatrix.m[1][3] + attachmatrix.m[1][0]*tagmatrix.m[0][3] + attachmatrix.m[1][1]*tagmatrix.m[1][3] + attachmatrix.m[1][2]*tagmatrix.m[2][3];
- out->m[2][3] = attachmatrix.m[2][3] + attachmatrix.m[2][0]*tagmatrix.m[0][3] + attachmatrix.m[2][1]*tagmatrix.m[1][3] + attachmatrix.m[2][2]*tagmatrix.m[2][3];
Matrix4x4_Copy(&tagmatrix, out);
ent = attachent;
if (attachloop > 255) // prevent runaway looping
return 5;
}
- while ((val = PRVM_GETEDICTFIELDVALUE(ent, csqc_fieldoff_tag_entity)) && val->edict);
+ while ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict);
}
// normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain)
- val = PRVM_GETEDICTFIELDVALUE(ent, csqc_fieldoff_scale);
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
if (val->_float == 0)
val->_float = 1;
// Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype...
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);
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
- out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
- out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
- out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
- if ((val = PRVM_GETEDICTFIELDVALUE(ent, csqc_fieldoff_renderflags)) && (RF_VIEWMODEL & (int)val->_float))
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && (RF_VIEWMODEL & (int)val->_float))
{// RENDER_VIEWMODEL magic
Matrix4x4_Copy(&tagmatrix, out);
- val = PRVM_GETEDICTFIELDVALUE(ent, csqc_fieldoff_scale);
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
if (val->_float == 0)
val->_float = 1;
Matrix4x4_CreateFromQuakeEntity(&entitymatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], val->_float);
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
- out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
- out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
- out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
/*
// Cl_bob, ported from rendering code
// (don't count Z, or jumping messes it up)
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;
bob = bob*0.3 + bob*0.7*cycle;
- out->m[2][3] += bound(-7, bob, 4);
+ Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
}
*/
}
VM_SAFEPARMCOUNT(1, VM_WasFreed);
e = PRVM_G_EDICT(OFS_PARM0);
- if (!e->priv.required->free || (e->priv.required->free && (e->priv.required->freetime < 2 || (*prog->time - e->priv.required->freetime) > 0.5 )))
+ if (!e->priv.required->free || (e->priv.required->free && (e->priv.required->freetime < 2 || (prog->globals.client->time - e->priv.required->freetime) > 0.5 )))
PRVM_G_FLOAT(OFS_RETURN) = false;
else
PRVM_G_FLOAT(OFS_RETURN) = true;
void VM_CL_select_cube (void)
{
int i;
- int chain_of;
float *mins2, *maxs2;
prvm_edict_t *ent, *chain;
vec3_t mins1, maxs1;
VM_SAFEPARMCOUNT(2, VM_CL_select_cube);
- // is the same like !(prog->flag & PRVM_FE_CHAIN) - even if the operator precedence is another
- if(!prog->flag & PRVM_FE_CHAIN)
+ if (prog->fieldoffsets.chain < 0)
PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
- chain_of = PRVM_ED_FindField("chain")->ofs;
chain = prog->edicts;
mins2 = PRVM_G_VECTOR(OFS_PARM0);
continue;
if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2])
continue;
- PRVM_E_INT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
+ PRVM_EDICTFIELDVALUE(ent,prog->fieldoffsets.chain)->edict = PRVM_NUM_FOR_EDICT(chain);
chain = ent;
}
void VM_CL_select_super (void)
{
/* int i;
- int chain_of;
float *v[8];
prvm_edict_t *ent, *chain;
vec3_t mins1, maxs1;
for(i=0;i<8;i++)
v[i] = PRVM_G_VECTOR(OFS_PARM0+i*3);
- // is the same like !(prog->flag & PRVM_FE_CHAIN) - even if the operator precedence is another
- if(!prog->flag & PRVM_FE_CHAIN)
+ if (prog->fieldoffsets.chain < 0)
PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
- chain_of = PRVM_ED_FindField("chain")->ofs;
chain = prog->edicts;
mins2 = PRVM_G_VECTOR(OFS_PARM0);
continue;
if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2])
continue;
- PRVM_E_INT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
+ PRVM_EDICTFIELDVALUE(ent,prog->fieldoffsets.chain)->edict = PRVM_NUM_FOR_EDICT(chain);
chain = ent;
}
void VM_uncolorstring (void) //#170
{
const char *in;
- char *out;
+ char out[VM_STRINGTEMP_LENGTH];
int k = 0, i = 0;
VM_SAFEPARMCOUNT(1, VM_uncolorstring);
in = PRVM_G_STRING(OFS_PARM0);
- if(!in)
- PRVM_ERROR ("VM_uncolorstring: %s: NULL\n", PRVM_NAME);
VM_CheckEmptyString (in);
- out = VM_GetTempString();
while (in[k])
{
++k;
++i;
}
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(out);
}
void VM_CL_selecttraceline (void)
csqcents = (int)PRVM_G_FLOAT(OFS_PARM3);
ent = 0;
- if((csqcents && ignore > cl.num_csqcentities) || (!csqcents && ignore > cl.num_entities))
+ if (csqcents)
{
- VM_Warning("VM_CL_selecttraceline: out of entities\n");
+ VM_Warning("VM_CL_selecttraceline: csqcents flag not supported anymore, and this function is deprecated\n");
return;
}
- else
- if(csqcents)
- prog->globals.client->trace_fraction = CL_SelectTraceLine(v1, v2, prog->globals.client->trace_endpos, prog->globals.client->trace_plane_normal, &prog->globals.client->trace_ent, &cl.csqcentities[ignore].render, csqcents);
- else
- 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, csqcents);
+ 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);
PRVM_G_FLOAT(OFS_RETURN) = ent;
}
{
const char *s;
s = PRVM_G_STRING(OFS_PARM0);
- if(!s)
- return;
if((unsigned)PRVM_G_FLOAT(OFS_PARM1) > strlen(s))
return;
PRVM_G_FLOAT(OFS_RETURN) = (unsigned char)s[(int)PRVM_G_FLOAT(OFS_PARM1)];
//#223 string(float c, ...) chr2str (FTE_STRINGS)
void VM_chr2str (void)
{
- char *t;
+ char t[128];
int i;
- t = VM_GetTempString();
- for(i=0;i<prog->argc;i++)
+ for(i = 0;i < prog->argc && i < (int)sizeof(t) - 1;i++)
t[i] = (unsigned char)PRVM_G_FLOAT(OFS_PARM0+i*3);
t[i] = 0;
- PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(t);
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
}
//#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
VM_localcmd, // #46 void(string s) localcmd
VM_nextent, // #47 entity(entity e) nextent
VM_CL_particle, // #48 void(vector o, vector d, float color, float count) particle
-VM_CL_changeyaw, // #49 void(entity ent, float ideal_yaw, float speed_yaw) ChangeYaw
+VM_changeyaw, // #49 void(entity ent) ChangeYaw
NULL, // #50
VM_vectoangles, // #51 vector(vector v) vectoangles
0, // #52 void(float to, float f) WriteByte
VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
-VM_CL_changepitch, // #63 void(entity ent, float ideal_pitch, float speed_pitch) changepitch (DP_QC_CHANGEPITCH)
+VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
VM_CL_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS)
NULL, // #66
VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
-e10, e10, e10 // #470-499 (LordHavoc)
+NULL, // #470
+VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
+VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
+VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
+VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
+VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
+VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
+VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
+VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
+NULL, // #479
+e10, e10 // #480-499 (LordHavoc)
};
const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);