X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=svvm_cmds.c;h=030bb92bf3bdc6ff478ea24f78de3cce97de2dd7;hp=9bb99eb8dd0c1a08a1a784bcad9443bf51a54776;hb=c0b8da8b7012a02ffd416d83840ad2bae7056191;hpb=dd3e7334d7c42bb4c8191fecbedb44525414ddb4 diff --git a/svvm_cmds.c b/svvm_cmds.c index 9bb99eb8..030bb92b 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 " @@ -31,11 +32,13 @@ char *vm_sv_extensions = "DP_EF_NOSHADOW " "DP_EF_RED " "DP_EF_STARDUST " +"DP_EF_TELEPORT_BIT " "DP_ENT_ALPHA " "DP_ENT_COLORMOD " "DP_ENT_CUSTOMCOLORMAP " "DP_ENT_EXTERIORMODELTOCLIENT " "DP_ENT_GLOW " +"DP_ENT_GLOWMOD " "DP_ENT_LOWPRECISION " "DP_ENT_SCALE " "DP_ENT_VIEWMODEL " @@ -46,6 +49,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 " @@ -62,12 +66,16 @@ char *vm_sv_extensions = "DP_QC_COPYENTITY " "DP_QC_CRC16 " "DP_QC_CVAR_DEFSTRING " +"DP_QC_CVAR_DESCRIPTION " "DP_QC_CVAR_STRING " "DP_QC_CVAR_TYPE " "DP_QC_EDICT_NUM " "DP_QC_ENTITYDATA " +"DP_QC_ENTITYSTRING " "DP_QC_ETOS " +"DP_QC_EXTRESPONSEPACKET " "DP_QC_FINDCHAIN " +"DP_QC_FINDCHAIN_TOFIELD " "DP_QC_FINDCHAINFLAGS " "DP_QC_FINDCHAINFLOAT " "DP_QC_FINDFLAGS " @@ -77,6 +85,10 @@ char *vm_sv_extensions = "DP_QC_GETSURFACE " "DP_QC_GETSURFACEPOINTATTRIBUTE " "DP_QC_GETTAGINFO " +"DP_QC_GETTAGINFO_BONEPROPERTIES " +"DP_QC_GETTIME " +"DP_QC_GETTIME_CDTRACK " +"DP_QC_LOG " "DP_QC_MINMAXBOUND " "DP_QC_MULTIPLETEMPSTRINGS " "DP_QC_NUM_FOR_EDICT " @@ -84,6 +96,7 @@ char *vm_sv_extensions = "DP_QC_SINCOSSQRTPOW " "DP_QC_STRFTIME " "DP_QC_STRINGBUFFERS " +"DP_QC_STRINGBUFFERS_CVARLIST " "DP_QC_STRINGCOLORFUNCTIONS " "DP_QC_STRING_CASE_FUNCTIONS " "DP_QC_STRREPLACE " @@ -111,6 +124,7 @@ char *vm_sv_extensions = "DP_SOLIDCORPSE " "DP_SPRITE32 " "DP_SV_BOTCLIENT " +"DP_SV_BOUNCEFACTOR " "DP_SV_CLIENTCOLORS " "DP_SV_CLIENTNAME " "DP_SV_CMD " @@ -124,6 +138,7 @@ char *vm_sv_extensions = "DP_SV_NETADDRESS " "DP_SV_NODRAWTOCLIENT " "DP_SV_ONENTITYNOSPAWNFUNCTION " +"DP_SV_ONENTITYPREPOSTSPAWNFUNCTION " "DP_SV_PING " "DP_SV_PLAYERPHYSICS " "DP_SV_POINTPARTICLES " @@ -154,8 +169,10 @@ char *vm_sv_extensions = "DP_TE_STANDARDEFFECTBUILTINS " "DP_TRACE_HITCONTENTSMASK_SURFACEINFO " "DP_VIEWZOOM " +"DP_LIGHTSTYLE_STATICVALUE " "EXT_BITSHIFT " "FRIK_FILE " +"FTE_QC_CHECKPVS " "FTE_STRINGS " "KRIMZON_SV_PARSECLIENTCOMMAND " "NEH_CMD_PLAY2 " @@ -165,6 +182,10 @@ char *vm_sv_extensions = "PRYDON_CLIENTCURSOR " "TENEBRAE_GFX_DLIGHTS " "TW_SV_STEPCONTROL " +"ZQ_PAUSE " +"DP_CSQC_SPAWNPARTICLE " +"DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET " +"DP_CSQC_ENTITYNOCULL " //"EXT_CSQC " // not ready yet ; @@ -197,7 +218,7 @@ static void VM_SV_setorigin (void) } org = PRVM_G_VECTOR(OFS_PARM1); VectorCopy (org, e->fields.server->origin); - SV_LinkEdict (e, false); + SV_LinkEdict(e); } // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black] @@ -214,7 +235,7 @@ static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rot VectorCopy (max, e->fields.server->maxs); VectorSubtract (max, min, e->fields.server->size); - SV_LinkEdict (e, false); + SV_LinkEdict(e); } /* @@ -565,10 +586,10 @@ 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)); + trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent)); VM_SetTraceGlobals(&trace); } @@ -604,10 +625,10 @@ 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)); + trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent)); VM_SetTraceGlobals(&trace); } @@ -634,7 +655,7 @@ static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore) gravity = val->_float; else gravity = 1.0; - gravity *= sv_gravity.value * 0.05; + gravity *= sv_gravity.value * 0.025; for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds { @@ -643,8 +664,9 @@ static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore) VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles); VectorScale (tossent->fields.server->velocity, 0.05, move); VectorAdd (tossent->fields.server->origin, move, end); - trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent)); + trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent)); VectorCopy (trace.endpos, tossent->fields.server->origin); + tossent->fields.server->velocity[2] -= gravity; if (trace.fraction < 1) break; @@ -780,6 +802,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 +} + /* ================= @@ -830,8 +918,16 @@ static void VM_SV_findradius (void) 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; @@ -874,7 +970,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; } } @@ -988,19 +1084,19 @@ static void VM_SV_droptofloor (void) if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer) SV_UnstickEntity(ent); - trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); + trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer) { vec3_t offset, org; VectorSet(offset, 0.5f * (ent->fields.server->mins[0] + ent->fields.server->maxs[0]), 0.5f * (ent->fields.server->mins[1] + ent->fields.server->maxs[1]), ent->fields.server->mins[2]); VectorAdd(ent->fields.server->origin, offset, org); - trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); + trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); VectorSubtract(trace.endpos, offset, trace.endpos); if (trace.startsolid) { Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]); SV_UnstickEntity(ent); - SV_LinkEdict (ent, false); + SV_LinkEdict(ent); ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; ent->fields.server->groundentity = 0; PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -1010,7 +1106,7 @@ static void VM_SV_droptofloor (void) Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]); VectorCopy (trace.endpos, ent->fields.server->origin); SV_UnstickEntity(ent); - SV_LinkEdict (ent, false); + SV_LinkEdict(ent); ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent); PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -1024,7 +1120,7 @@ static void VM_SV_droptofloor (void) { if (trace.fraction < 1) VectorCopy (trace.endpos, ent->fields.server->origin); - SV_LinkEdict (ent, false); + SV_LinkEdict(ent); ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent); PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -1141,7 +1237,7 @@ static void VM_SV_aim (void) // try sending a trace straight VectorCopy (prog->globals.server->v_forward, dir); VectorMA (start, 2048, dir, end); - tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY); + tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY); if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) ) { @@ -1173,7 +1269,7 @@ static void VM_SV_aim (void) dist = DotProduct (dir, prog->globals.server->v_forward); if (dist < bestdist) continue; // to far to turn - tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY); + tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY); if (tr.ent == check) { // can shoot at this one bestdist = dist; @@ -1318,7 +1414,7 @@ static void VM_SV_WritePicture (void) VM_SAFEPARMCOUNT(3, VM_SV_WritePicture); imgname = PRVM_G_STRING(OFS_PARM1); - size = PRVM_G_FLOAT(OFS_PARM2); + size = (int) PRVM_G_FLOAT(OFS_PARM2); if(size > 65535) size = 65535; @@ -1327,7 +1423,7 @@ static void VM_SV_WritePicture (void) { // actual picture MSG_WriteShort(WriteDest(), size); - SZ_Write(WriteDest(), buf, size); + SZ_Write(WriteDest(), (unsigned char *) buf, size); } else { @@ -1593,7 +1689,7 @@ static void VM_SV_copyentity (void) return; } memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4); - SV_LinkEdict(out, false); + SV_LinkEdict(out); } @@ -2489,17 +2585,57 @@ int SV_GetTagIndex (prvm_edict_t *e, const char *tagname) 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) { - float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float; - if (scale == 0) - scale = 1; + prvm_eval_t *val; + float scale; + float pitchsign = 1; + + 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); + { + pitchsign = SV_GetPitchSign(ent); + Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], pitchsign * 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) @@ -2548,7 +2684,7 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) return 2; modelindex = (int)ent->fields.server->modelindex; - if (modelindex <= 0 || modelindex > MAX_MODELS) + if (modelindex <= 0 || modelindex >= MAX_MODELS) return 3; model = sv.models[modelindex]; @@ -2565,9 +2701,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) { @@ -2640,7 +2776,7 @@ static void VM_SV_gettagindex (void) modelindex = (int)ent->fields.server->modelindex; tag_index = 0; - if (modelindex <= 0 || modelindex > MAX_MODELS) + if (modelindex <= 0 || modelindex >= MAX_MODELS) Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent)); else { @@ -2650,7 +2786,7 @@ static void VM_SV_gettagindex (void) Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name); } PRVM_G_FLOAT(OFS_RETURN) = tag_index; -}; +} //vector(entity ent, float tagindex) gettaginfo; static void VM_SV_gettaginfo (void) @@ -2658,7 +2794,12 @@ static void VM_SV_gettaginfo (void) 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, le, up, trans; VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo); @@ -2666,7 +2807,23 @@ 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, le, 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))) + VectorScale(le, -1, val->vector); + if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up))) + VectorCopy(up, val->vector); switch(returncode) { @@ -2786,7 +2943,7 @@ static void VM_SV_setmodelindex (void) return; } i = (int)PRVM_G_FLOAT(OFS_PARM1); - if (i <= 0 || i > MAX_MODELS) + if (i <= 0 || i >= MAX_MODELS) { VM_Warning("setmodelindex: invalid modelindex\n"); return; @@ -2822,7 +2979,7 @@ static void VM_SV_modelnameforindex (void) PRVM_G_INT(OFS_RETURN) = OFS_NULL; i = (int)PRVM_G_FLOAT(OFS_PARM0); - if (i <= 0 || i > MAX_MODELS) + if (i <= 0 || i >= MAX_MODELS) { VM_Warning("modelnameforindex: invalid modelindex\n"); return; @@ -2897,6 +3054,24 @@ static void VM_SV_pointparticles (void) 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) @@ -2914,7 +3089,7 @@ VM_vlen, // #12 float(vector v) vlen (QUAKE) VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE) VM_spawn, // #14 entity() spawn (QUAKE) VM_remove, // #15 void(entity e) remove (QUAKE) -VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE) +VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE) VM_SV_checkclient, // #17 entity() checkclient (QUAKE) VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE) VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE) @@ -3140,7 +3315,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 @@ -3419,9 +3594,115 @@ VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE) VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE) VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE) -NULL, // #517 -NULL, // #518 -NULL, // #519 +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) +VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME) +NULL, // #520 +NULL, // #521 +NULL, // #522 +NULL, // #523 +NULL, // #524 +NULL, // #525 +NULL, // #526 +NULL, // #527 +NULL, // #528 +VM_loadfromdata, // #529 +VM_loadfromfile, // #530 +VM_SV_setpause, // #531 void(float pause) setpause = #531; +VM_log, // #532 +NULL, // #533 +NULL, // #534 +NULL, // #535 +NULL, // #536 +NULL, // #537 +NULL, // #538 +NULL, // #539 +NULL, // #540 +NULL, // #541 +NULL, // #542 +NULL, // #543 +NULL, // #544 +NULL, // #545 +NULL, // #546 +NULL, // #547 +NULL, // #548 +NULL, // #549 +NULL, // #550 +NULL, // #551 +NULL, // #552 +NULL, // #553 +NULL, // #554 +NULL, // #555 +NULL, // #556 +NULL, // #557 +NULL, // #558 +NULL, // #559 +NULL, // #560 +NULL, // #561 +NULL, // #562 +NULL, // #563 +NULL, // #564 +NULL, // #565 +NULL, // #566 +NULL, // #567 +NULL, // #568 +NULL, // #569 +NULL, // #570 +NULL, // #571 +NULL, // #572 +NULL, // #573 +NULL, // #574 +NULL, // #575 +NULL, // #576 +NULL, // #577 +NULL, // #578 +NULL, // #579 +NULL, // #580 +NULL, // #581 +NULL, // #582 +NULL, // #583 +NULL, // #584 +NULL, // #585 +NULL, // #586 +NULL, // #587 +NULL, // #588 +NULL, // #589 +NULL, // #590 +NULL, // #591 +NULL, // #592 +NULL, // #593 +NULL, // #594 +NULL, // #595 +NULL, // #596 +NULL, // #597 +NULL, // #598 +NULL, // #599 +NULL, // #600 +NULL, // #601 +NULL, // #602 +NULL, // #603 +NULL, // #604 +VM_callfunction, // #605 +VM_writetofile, // #606 +VM_isfunction, // #607 +NULL, // #608 +NULL, // #609 +NULL, // #610 +NULL, // #611 +NULL, // #612 +VM_parseentitydata, // #613 +NULL, // #614 +NULL, // #615 +NULL, // #616 +NULL, // #617 +NULL, // #618 +NULL, // #619 +NULL, // #620 +NULL, // #621 +NULL, // #622 +NULL, // #623 +VM_getextresponse, // #624 string getextresponse(void) +NULL, // #625 }; const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t); @@ -3433,6 +3714,7 @@ void VM_SV_Cmd_Init(void) void VM_SV_Cmd_Reset(void) { + World_End(&sv.world); if(prog->funcoffsets.SV_Shutdown) { func_t s = prog->funcoffsets.SV_Shutdown;