X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=svvm_cmds.c;h=7243558dbb22123092a78972900c1ad3df3cdc1e;hb=140a0f8e823a43dcc44f2670d48416ab48f9c243;hp=0bd684c91c752af429d6b481cb9c897c884c00e8;hpb=c3ea7019c9ce6dd91e6f40a027a45cd27da17385;p=xonotic%2Fdarkplaces.git diff --git a/svvm_cmds.c b/svvm_cmds.c index 0bd684c9..7243558d 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -19,6 +19,7 @@ char *vm_sv_extensions = "DP_CON_SET " "DP_CON_SETA " "DP_CON_STARTMAP " +"DP_CSQC_MULTIFRAME_INTERPOLATION " "DP_EF_ADDITIVE " "DP_EF_BLUE " "DP_EF_DOUBLESIDED " @@ -47,6 +48,7 @@ char *vm_sv_extensions = "DP_GFX_QUAKE3MODELTAGS " "DP_GFX_SKINFILES " "DP_GFX_SKYBOX " +"DP_GFX_MODEL_INTERPOLATION " "DP_HALFLIFE_MAP " "DP_HALFLIFE_MAP_CVAR " "DP_HALFLIFE_SPRITE " @@ -70,6 +72,7 @@ char *vm_sv_extensions = "DP_QC_ENTITYDATA " "DP_QC_ETOS " "DP_QC_FINDCHAIN " +"DP_QC_FINDCHAIN_TOFIELD " "DP_QC_FINDCHAINFLAGS " "DP_QC_FINDCHAINFLOAT " "DP_QC_FINDFLAGS " @@ -80,6 +83,7 @@ char *vm_sv_extensions = "DP_QC_GETSURFACEPOINTATTRIBUTE " "DP_QC_GETTAGINFO " "DP_QC_GETTAGINFO_BONEPROPERTIES " +"DP_QC_GETTIME " "DP_QC_MINMAXBOUND " "DP_QC_MULTIPLETEMPSTRINGS " "DP_QC_NUM_FOR_EDICT " @@ -161,6 +165,7 @@ char *vm_sv_extensions = "DP_VIEWZOOM " "EXT_BITSHIFT " "FRIK_FILE " +"FTE_QC_CHECKPVS " "FTE_STRINGS " "KRIMZON_SV_PARSECLIENTCOMMAND " "NEH_CMD_PLAY2 " @@ -571,7 +576,7 @@ static void VM_SV_traceline (void) move = (int)PRVM_G_FLOAT(OFS_PARM2); ent = PRVM_G_EDICT(OFS_PARM3); - if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2])) + if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2])) PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent)); trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent)); @@ -610,7 +615,7 @@ static void VM_SV_tracebox (void) move = (int)PRVM_G_FLOAT(OFS_PARM4); ent = PRVM_G_EDICT(OFS_PARM5); - if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2])) + if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2])) PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent)); trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent)); @@ -787,6 +792,72 @@ static void VM_SV_checkclient (void) //============================================================================ +/* +================= +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 +} + /* ================= @@ -837,8 +908,16 @@ static void VM_SV_findradius (void) int i; int numtouchedicts; prvm_edict_t *touchedicts[MAX_EDICTS]; + int chainfield; + + VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius); - VM_SAFEPARMCOUNT(2, 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; @@ -881,7 +960,7 @@ static void VM_SV_findradius (void) 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; } } @@ -2531,13 +2610,36 @@ int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, cons void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix) { - float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float; - if (scale == 0) - scale = 1; + prvm_eval_t *val; + float scale; + float WTFsign; + int modelindex; + dp_model_t *model; + + scale = 1; + val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale); + if (val && val->_float != 0) + scale = val->_float; + if (viewmatrix) - Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], scale); + Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], scale * cl_viewmodel_scale.value); else - Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale * cl_viewmodel_scale.value); + { + WTFsign = 1; + if ( + ((modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS && (model = sv.models[(int)ent->fields.server->modelindex])) + ? + model->type == mod_alias + : + ( + (((unsigned char)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.pflags)->_float) & PFLAGS_FULLDYNAMIC) + || + ((gamemode == GAME_TENEBRAE) && ((unsigned int)ent->fields.server->effects & (16 | 32))) + ) + ) + WTFsign = -1; + Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], WTFsign * ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale); + } } int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out) @@ -2603,9 +2705,9 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix); if (ret && attachloop == 0) return ret; - Matrix4x4_Concat(out, &attachmatrix, &tagmatrix); SV_GetEntityMatrix(ent, &entitymatrix, false); - Matrix4x4_Concat(&tagmatrix, &entitymatrix, out); + Matrix4x4_Concat(&tagmatrix, &attachmatrix, out); + Matrix4x4_Concat(out, &entitymatrix, &tagmatrix); // next iteration we process the parent entity if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict) { @@ -2701,7 +2803,7 @@ static void VM_SV_gettaginfo (void) const char *tagname; int returncode; prvm_eval_t *val; - vec3_t fo, ri, up, trans; + vec3_t fo, le, up, trans; VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo); @@ -2709,9 +2811,10 @@ static void VM_SV_gettaginfo (void) tagindex = (int)PRVM_G_FLOAT(OFS_PARM1); 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)); + Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN)); + VectorScale(le, -1, prog->globals.server->v_right); SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix); - Matrix4x4_ToVectors(&tag_localmatrix, fo, ri, up, trans); + Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans); if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent))) val->_float = parentindex; @@ -2722,7 +2825,7 @@ static void VM_SV_gettaginfo (void) if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward))) VectorCopy(fo, val->vector); if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right))) - VectorCopy(ri, val->vector); + VectorScale(le, -1, val->vector); if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up))) VectorCopy(up, val->vector); @@ -3216,7 +3319,7 @@ NULL, // #236 NULL, // #237 NULL, // #238 NULL, // #239 -NULL, // #240 +VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs; NULL, // #241 NULL, // #242 NULL, // #243 @@ -3497,7 +3600,7 @@ VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_Q VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE) 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 +VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME) NULL, // #520 NULL, // #521 NULL, // #522