"DP_EF_NOSHADOW "
"DP_EF_RED "
"DP_EF_STARDUST "
+"DP_EF_TELEPORT_BIT "
"DP_ENT_ALPHA "
"DP_ENT_COLORMOD "
"DP_ENT_CUSTOMCOLORMAP "
"DP_QC_ENTITYDATA "
"DP_QC_ETOS "
"DP_QC_FINDCHAIN "
+"DP_QC_FINDCHAIN_TOFIELD "
"DP_QC_FINDCHAINFLAGS "
"DP_QC_FINDCHAINFLOAT "
"DP_QC_FINDFLAGS "
"DP_QC_GETSURFACE "
"DP_QC_GETSURFACEPOINTATTRIBUTE "
"DP_QC_GETTAGINFO "
+"DP_QC_GETTAGINFO_BONEPROPERTIES "
"DP_QC_MINMAXBOUND "
"DP_QC_MULTIPLETEMPSTRINGS "
"DP_QC_NUM_FOR_EDICT "
"DP_VIEWZOOM "
"EXT_BITSHIFT "
"FRIK_FILE "
+"FTE_QC_CHECKPVS "
"FTE_STRINGS "
"KRIMZON_SV_PARSECLIENTCOMMAND "
"NEH_CMD_PLAY2 "
"PRYDON_CLIENTCURSOR "
"TENEBRAE_GFX_DLIGHTS "
"TW_SV_STEPCONTROL "
+"ZQ_PAUSE "
//"EXT_CSQC " // not ready yet
;
//============================================================================
+/*
+=================
+VM_SV_checkpvs
+
+Checks if an entity is in a point's PVS.
+Should be fast but can be inexact.
+
+float checkpvs(vector viewpos, entity viewee) = #240;
+=================
+*/
+static void VM_SV_checkpvs (void)
+{
+ vec3_t viewpos;
+ prvm_edict_t *viewee;
+#if 1
+ unsigned char *pvs;
+#else
+ static int fatpvsbytes;
+ static unsigned char fatpvs[MAX_MAP_LEAFS/8];
+#endif
+
+ VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
+ viewee = PRVM_G_EDICT(OFS_PARM1);
+
+ if(viewee->priv.server->free)
+ {
+ VM_Warning("checkpvs: can not check free entity\n");
+ PRVM_G_FLOAT(OFS_RETURN) = 4;
+ return;
+ }
+
+#if 1
+ if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+ {
+ // no PVS support on this worldmodel... darn
+ PRVM_G_FLOAT(OFS_RETURN) = 3;
+ return;
+ }
+ pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
+ if(!pvs)
+ {
+ // viewpos isn't in any PVS... darn
+ PRVM_G_FLOAT(OFS_RETURN) = 2;
+ return;
+ }
+ PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
+#else
+ // using fat PVS like FTEQW does (slow)
+ if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+ {
+ // no PVS support on this worldmodel... darn
+ PRVM_G_FLOAT(OFS_RETURN) = 3;
+ return;
+ }
+ fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
+ if(!fatpvsbytes)
+ {
+ // viewpos isn't in any PVS... darn
+ PRVM_G_FLOAT(OFS_RETURN) = 2;
+ return;
+ }
+ PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
+#endif
+}
+
/*
=================
int i;
int numtouchedicts;
prvm_edict_t *touchedicts[MAX_EDICTS];
+ int chainfield;
- VM_SAFEPARMCOUNT(2, VM_SV_findradius);
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
+
+ if(prog->argc == 3)
+ chainfield = PRVM_G_INT(OFS_PARM2);
+ else
+ chainfield = prog->fieldoffsets.chain;
+ if (chainfield < 0)
+ PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
chain = (prvm_edict_t *)prog->edicts;
VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
if (DotProduct(eorg, eorg) < radius2)
{
- ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
+ PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
chain = ent;
}
}
model = sv.models[i];
return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
-};
+}
+
+int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
+{
+ int r;
+ dp_model_t *model;
+ int frame;
+ int modelindex;
+
+ *tagname = NULL;
+ *parentindex = 0;
+ Matrix4x4_CreateIdentity(tag_localmatrix);
+
+ if (tagindex >= 0
+ && (modelindex = (int)e->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
+ && (model = sv.models[(int)e->fields.server->modelindex])
+ && model->animscenes)
+ {
+ frame = (int)e->fields.server->frame;
+ if (frame < 0 || frame >= model->numframes)
+ frame = 0;
+
+ r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, model->animscenes[frame].firstframe, tagindex - 1, parentindex, tagname, tag_localmatrix);
+
+ if(!r) // success?
+ *parentindex += 1;
+
+ return r;
+ }
+
+ return 1;
+}
void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
{
prvm_edict_t *e;
int tagindex;
matrix4x4_t tag_matrix;
+ matrix4x4_t tag_localmatrix;
+ int parentindex;
+ const char *tagname;
int returncode;
+ prvm_eval_t *val;
+ vec3_t fo, ri, up, trans;
VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
+ SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
+ Matrix4x4_ToVectors(&tag_localmatrix, fo, ri, up, trans);
+
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
+ val->_float = parentindex;
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
+ val->string = tagname ? PRVM_SetTempString(tagname) : 0;
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
+ VectorCopy(trans, val->vector);
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
+ VectorCopy(fo, val->vector);
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
+ VectorCopy(ri, val->vector);
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
+ VectorCopy(up, val->vector);
switch(returncode)
{
SV_FlushBroadcastMessages();
}
+//PF_setpause, // void(float pause) setpause = #531;
+static void VM_SV_setpause(void) {
+ int pauseValue;
+ pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
+ if (pauseValue != 0) { //pause the game
+ sv.paused = 1;
+ sv.pausedstart = Sys_DoubleTime();
+ } else { //disable pause, in case it was enabled
+ if (sv.paused != 0) {
+ sv.paused = 0;
+ sv.pausedstart = 0;
+ }
+ }
+ // send notification to all clients
+ MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
+ MSG_WriteByte(&sv.reliable_datagram, sv.paused);
+}
+
prvm_builtin_t vm_sv_builtins[] = {
NULL, // #0 NULL function (not callable) (QUAKE)
VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
NULL, // #237
NULL, // #238
NULL, // #239
-NULL, // #240
+VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
NULL, // #241
NULL, // #242
NULL, // #243
VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
NULL, // #519
+NULL, // #520
+NULL, // #521
+NULL, // #522
+NULL, // #523
+NULL, // #524
+NULL, // #525
+NULL, // #526
+NULL, // #527
+NULL, // #528
+NULL, // #529
+NULL, // #530
+VM_SV_setpause, // #531 void(float pause) setpause = #531;
+NULL, // #532
};
const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);