X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=svvm_cmds.c;h=12ef69dab455c345729fb55c0bcb73a7f5e81adb;hb=6b72cddee4efc077bfe7ce185ada0e5c15332d4d;hp=c75dd07740ae4599409952601096c7937909179e;hpb=97703839c970c295ba6173da463906bdec6d55cd;p=xonotic%2Fdarkplaces.git diff --git a/svvm_cmds.c b/svvm_cmds.c index c75dd077..12ef69da 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -19,6 +19,7 @@ const char *vm_sv_extensions = "DP_CON_SET " "DP_CON_SETA " "DP_CON_STARTMAP " +"DP_COVERAGE " "DP_CRYPTO " "DP_CSQC_BINDMAPS " "DP_CSQC_ENTITYWORLDOBJECT " @@ -167,6 +168,7 @@ const char *vm_sv_extensions = "DP_SV_CLIENTNAME " "DP_SV_CMD " "DP_SV_CUSTOMIZEENTITYFORCLIENT " +"DP_SV_DISABLECLIENTPREDICTION " "DP_SV_DISCARDABLEDEMO " "DP_SV_DRAWONLYTOCLIENT " "DP_SV_DROPCLIENT " @@ -209,6 +211,7 @@ const char *vm_sv_extensions = "DP_TE_SPARK " "DP_TE_STANDARDEFFECTBUILTINS " "DP_TRACE_HITCONTENTSMASK_SURFACEINFO " +"DP_USERMOVETYPES " "DP_VIEWZOOM " "EXT_BITSHIFT " "FRIK_FILE " @@ -224,6 +227,7 @@ const char *vm_sv_extensions = "TENEBRAE_GFX_DLIGHTS " "TW_SV_STEPCONTROL " "ZQ_PAUSE " +"DP_RM_CLIPGROUP " //"EXT_CSQC " // not ready yet ; @@ -240,7 +244,7 @@ static void VM_SV_setorigin(prvm_prog_t *prog) { prvm_edict_t *e; - VM_SAFEPARMCOUNT(2, VM_setorigin); + VM_SAFEPARMCOUNT(2, VM_SV_setorigin); e = PRVM_G_EDICT(OFS_PARM0); if (e == prog->edicts) @@ -281,7 +285,7 @@ static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float VM_SV_setsize the size box is rotated by the current angle -LordHavoc: no it isn't... +LadyHavoc: no it isn't... setsize (entity, minvector, maxvector) ================= @@ -291,7 +295,7 @@ static void VM_SV_setsize(prvm_prog_t *prog) prvm_edict_t *e; vec3_t mins, maxs; - VM_SAFEPARMCOUNT(3, VM_setsize); + VM_SAFEPARMCOUNT(3, VM_SV_setsize); e = PRVM_G_EDICT(OFS_PARM0); if (e == prog->edicts) @@ -324,7 +328,7 @@ static void VM_SV_setmodel(prvm_prog_t *prog) dp_model_t *mod; int i; - VM_SAFEPARMCOUNT(2, VM_setmodel); + VM_SAFEPARMCOUNT(2, VM_SV_setmodel); e = PRVM_G_EDICT(OFS_PARM0); if (e == prog->edicts) @@ -374,7 +378,7 @@ static void VM_SV_sprint(prvm_prog_t *prog) VM_VarString(prog, 1, string, sizeof(string)); entnum = PRVM_G_EDICTNUM(OFS_PARM0); - // LordHavoc: div0 requested that sprintto world operate like print + // LadyHavoc: div0 requested that sprintto world operate like print if (entnum == 0) { Con_Print(string); @@ -521,7 +525,7 @@ static void VM_SV_sound(prvm_prog_t *prog) const char *sample; int channel; prvm_edict_t *entity; - int volume; + int nvolume; int flags; float attenuation; float pitchchange; @@ -531,7 +535,7 @@ static void VM_SV_sound(prvm_prog_t *prog) entity = PRVM_G_EDICT(OFS_PARM0); channel = (int)PRVM_G_FLOAT(OFS_PARM1); sample = PRVM_G_STRING(OFS_PARM2); - volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255); + nvolume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255); if (prog->argc < 5) { Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n"); @@ -555,11 +559,11 @@ static void VM_SV_sound(prvm_prog_t *prog) } else { - // LordHavoc: we only let the qc set certain flags, others are off-limits - flags = (int)PRVM_G_FLOAT(OFS_PARM6) & (CHANNELFLAG_RELIABLE | CHANNELFLAG_FORCELOOP | CHANNELFLAG_PAUSED); + // LadyHavoc: we only let the qc set certain flags, others are off-limits + flags = (int)PRVM_G_FLOAT(OFS_PARM6) & (CHANNELFLAG_RELIABLE | CHANNELFLAG_FORCELOOP | CHANNELFLAG_PAUSED | CHANNELFLAG_FULLVOLUME); } - if (volume < 0 || volume > 255) + if (nvolume < 0 || nvolume > 255) { VM_Warning(prog, "SV_StartSound: volume must be in range 0-1\n"); return; @@ -579,7 +583,7 @@ static void VM_SV_sound(prvm_prog_t *prog) return; } - SV_StartSound (entity, channel, sample, volume, attenuation, flags & CHANNELFLAG_RELIABLE, pitchchange); + SV_StartSound (entity, channel, sample, nvolume, attenuation, flags & CHANNELFLAG_RELIABLE, pitchchange); } /* @@ -595,7 +599,7 @@ is omitted (since no entity is being tracked). static void VM_SV_pointsound(prvm_prog_t *prog) { const char *sample; - int volume; + int nvolume; float attenuation; float pitchchange; vec3_t org; @@ -604,11 +608,11 @@ static void VM_SV_pointsound(prvm_prog_t *prog) VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org); sample = PRVM_G_STRING(OFS_PARM1); - volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255); + nvolume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255); attenuation = PRVM_G_FLOAT(OFS_PARM3); pitchchange = prog->argc < 5 ? 0 : PRVM_G_FLOAT(OFS_PARM4) * 0.01f; - if (volume < 0 || volume > 255) + if (nvolume < 0 || nvolume > 255) { VM_Warning(prog, "SV_StartPointSound: volume must be in range 0-1\n"); return; @@ -620,7 +624,7 @@ static void VM_SV_pointsound(prvm_prog_t *prog) return; } - SV_StartPointSound (org, sample, volume, attenuation, pitchchange); + SV_StartPointSound (org, sample, nvolume, attenuation, pitchchange); } /* @@ -653,7 +657,7 @@ static void VM_SV_traceline(prvm_prog_t *prog) if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2])) prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent)); - trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent)); + trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendtracelinelength.value); VM_SetTraceGlobals(prog, &trace); } @@ -670,7 +674,7 @@ if the tryents flag is set. tracebox (vector1, vector mins, vector maxs, vector2, tryents) ================= */ -// LordHavoc: added this for my own use, VERY useful, similar to traceline +// LadyHavoc: added this for my own use, VERY useful, similar to traceline static void VM_SV_tracebox(prvm_prog_t *prog) { vec3_t v1, v2, m1, m2; @@ -692,7 +696,7 @@ static void VM_SV_tracebox(prvm_prog_t *prog) if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2])) prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->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_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent)); + trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendtraceboxlength.value); VM_SetTraceGlobals(prog, &trace); } @@ -718,7 +722,7 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic gravity = 1.0f; gravity *= sv_gravity.value * 0.025; - for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds + for (i = 0;i < 200;i++) // LadyHavoc: sanity check; never trace more than 10 seconds { SV_CheckVelocity (tossent); PRVM_serveredictvector(tossent, velocity)[2] -= gravity; @@ -728,7 +732,7 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic VectorCopy(PRVM_serveredictvector(tossent, origin), tossentorigin); VectorCopy(PRVM_serveredictvector(tossent, mins), tossentmins); VectorCopy(PRVM_serveredictvector(tossent, maxs), tossentmaxs); - trace = SV_TraceBox(tossentorigin, tossentmins, tossentmaxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent)); + trace = SV_TraceBox(tossentorigin, tossentmins, tossentmaxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent), 0, 0, collision_extendmovelength.value); VectorCopy (trace.endpos, PRVM_serveredictvector(tossent, origin)); PRVM_serveredictvector(tossent, velocity)[2] -= gravity; @@ -965,7 +969,7 @@ static void VM_SV_stuffcmd(prvm_prog_t *prog) old = host_client; host_client = svs.clients + entnum-1; - Host_ClientCommands ("%s", string); + SV_ClientCommands ("%s", string); host_client = old; } @@ -1024,7 +1028,7 @@ static void VM_SV_findradius(prvm_prog_t *prog) // (note: this is the reason you can't blow up fallen zombies) if (PRVM_serveredictfloat(ent, solid) == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer) continue; - // LordHavoc: compare against bounding box rather than center so it + // LadyHavoc: compare against bounding box rather than center so it // doesn't miss large objects, and use DotProduct instead of Length // for a major speedup VectorSubtract(org, PRVM_serveredictvector(ent, origin), eorg); @@ -1156,13 +1160,13 @@ static void VM_SV_droptofloor(prvm_prog_t *prog) VectorCopy(PRVM_serveredictvector(ent, origin), entorigin); VectorCopy(PRVM_serveredictvector(ent, mins), entmins); VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs); - trace = SV_TraceBox(entorigin, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); + trace = SV_TraceBox(entorigin, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value); if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer) { vec3_t offset, org; VectorSet(offset, 0.5f * (PRVM_serveredictvector(ent, mins)[0] + PRVM_serveredictvector(ent, maxs)[0]), 0.5f * (PRVM_serveredictvector(ent, mins)[1] + PRVM_serveredictvector(ent, maxs)[1]), PRVM_serveredictvector(ent, mins)[2]); VectorAdd(PRVM_serveredictvector(ent, origin), offset, org); - trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent)); + trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value); VectorSubtract(trace.endpos, offset, trace.endpos); if (trace.startsolid) { @@ -1263,7 +1267,7 @@ static void VM_SV_pointcontents(prvm_prog_t *prog) vec3_t point; VM_SAFEPARMCOUNT(1, VM_SV_pointcontents); VectorCopy(PRVM_G_VECTOR(OFS_PARM0), point); - PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(point)); + PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(SV_PointSuperContents(point)); } /* @@ -1310,7 +1314,7 @@ static void VM_SV_aim(prvm_prog_t *prog) // try sending a trace straight VectorCopy (PRVM_serverglobalvector(v_forward), dir); VectorMA (start, 2048, dir, end); - tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY); + tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, 0, 0, collision_extendmovelength.value); if (tr.ent && PRVM_serveredictfloat(((prvm_edict_t *)tr.ent), takedamage) == DAMAGE_AIM && (!teamplay.integer || PRVM_serveredictfloat(ent, team) <=0 || PRVM_serveredictfloat(ent, team) != PRVM_serveredictfloat(((prvm_edict_t *)tr.ent), team)) ) { @@ -1342,7 +1346,7 @@ static void VM_SV_aim(prvm_prog_t *prog) dist = DotProduct (dir, PRVM_serverglobalvector(v_forward)); if (dist < bestdist) continue; // to far to turn - tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY); + tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, 0, 0, collision_extendmovelength.value); if (tr.ent == check) { // can shoot at this one bestdist = dist; @@ -1495,8 +1499,8 @@ static void VM_SV_WritePicture(prvm_prog_t *prog) if(Image_Compress(imgname, size, &buf, &size)) { // actual picture - MSG_WriteShort(WriteDest(prog), size); - SZ_Write(WriteDest(prog), (unsigned char *) buf, size); + MSG_WriteShort(WriteDest(prog), (int)size); + SZ_Write(WriteDest(prog), (unsigned char *) buf, (int)size); } else { @@ -1623,21 +1627,17 @@ static void VM_SV_getlight(prvm_prog_t *prog) typedef struct { - unsigned char type; // 1/2/8 or other value if isn't used + unsigned char type; // 1/2/8 or 0 to indicate unused int fieldoffset; }customstat_t; -static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32 +static customstat_t vm_customstats[MAX_CL_STATS]; // matches the regular stat numbers, but only MIN_VM_STAT to MAX_VM_STAT range is used if things are working properly (can register stats from MAX_VM_STAT to MAX_CL_STATS but will warn) static int vm_customstats_last; void VM_CustomStats_Clear (void) { - if(vm_customstats) - { - Z_Free(vm_customstats); - vm_customstats = NULL; - vm_customstats_last = -1; - } + memset(vm_customstats, 0, sizeof(vm_customstats)); + vm_customstats_last = -1; } void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats) @@ -1645,11 +1645,12 @@ void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *ms prvm_prog_t *prog = SVVM_prog; int i; char s[17]; + union { + int i; + float f; + } u; - if(!vm_customstats) - return; - - for(i=0; i= (MAX_CL_STATS-32)) + + if (i >= MAX_CL_STATS) { - VM_Warning(prog, "PF_SV_AddStat: index >= MAX_CL_STATS\n"); + VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_CL_STATS (%i), not supported by protocol, and AddStat beyond MAX_VM_STAT (%i) conflicts with engine MOVEVARS\n", i, MAX_CL_STATS, MAX_VM_STAT); return; } - if(i > (MAX_CL_STATS-32-4) && type == 1) + + if (i > (MAX_CL_STATS - 4) && type == 1) { - VM_Warning(prog, "PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n"); + VM_Warning(prog, "PF_SV_AddStat: index (%i) > (MAX_CL_STATS (%i) - 4) with string type won't fit in the protocol, and AddStat beyond MAX_VM_STAT conflicts with engine MOVEVARS\n", i, MAX_CL_STATS); return; } + + // these are hazardous to override but sort of allowed if one wants to be adventurous... and enjoys warnings. + if (i < MIN_VM_STAT) + VM_Warning(prog, "PF_SV_AddStat: index (%i) < MIN_VM_STAT (%i) may conflict with engine stats - allowed, but this may break things\n", i, MIN_VM_STAT); + else if (i >= MAX_VM_STAT && !sv_gameplayfix_customstats.integer) + VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_VM_STAT (%i) conflicts with engine stats - allowed, but this may break slowmo and stuff\n", i, MAX_VM_STAT); + else if (i > (MAX_VM_STAT - 4) && type == 1 && !sv_gameplayfix_customstats.integer) + VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_VM_STAT (%i) - 4 with string type won't fit within MAX_VM_STAT, thus conflicting with engine stats - allowed, but this may break slowmo and stuff\n", i, MAX_VM_STAT); + vm_customstats[i].type = type; vm_customstats[i].fieldoffset = off; if(vm_customstats_last < i) @@ -1763,6 +1779,8 @@ static void VM_SV_copyentity(prvm_prog_t *prog) return; } memcpy(out->fields.fp, in->fields.fp, prog->entityfields * sizeof(prvm_vec_t)); + if (VectorCompare(PRVM_serveredictvector(out, absmin), PRVM_serveredictvector(out, absmax))) + return; SV_LinkEdict(out); } @@ -2318,7 +2336,7 @@ static void VM_SV_te_flamejet(prvm_prog_t *prog) } //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client -//this function originally written by KrimZon, made shorter by LordHavoc +//this function originally written by KrimZon, made shorter by LadyHavoc static void VM_SV_clientcommand(prvm_prog_t *prog) { client_t *temp_client; @@ -2335,7 +2353,7 @@ static void VM_SV_clientcommand(prvm_prog_t *prog) temp_client = host_client; host_client = svs.clients + i; - Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client, true); + Cmd_ExecuteString(&cmd_serverfromclient, PRVM_G_STRING(OFS_PARM1), src_client, true); host_client = temp_client; } @@ -2524,9 +2542,9 @@ static int SV_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *e if (PRVM_serveredictfloat(ent, health) > 0 && cl_bob.value && cl_bobcycle.value) { double bob, cycle; - // LordHavoc: this code is *weird*, but not replacable (I think it + // LadyHavoc: this code is *weird*, but not replacable (I think it // should be done in QC on the server, but oh well, quake is quake) - // LordHavoc: figured out bobup: the time at which the sin is at 180 + // LadyHavoc: figured out bobup: the time at which the sin is at 180 // degrees (which allows lengthening or squishing the peak or valley) cycle = sv.time/cl_bobcycle.value; cycle -= (int)cycle; @@ -2858,7 +2876,7 @@ static void VM_SV_setpause(prvm_prog_t *prog) { pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0); if (pauseValue != 0) { //pause the game sv.paused = 1; - sv.pausedstart = realtime; + sv.pausedstart = host.realtime; } else { //disable pause, in case it was enabled if (sv.paused != 0) { sv.paused = 0; @@ -3224,7 +3242,7 @@ NULL, // #42 (QUAKE) VM_fabs, // #43 float(float f) fabs (QUAKE) VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE) VM_cvar, // #45 float(string s) cvar (QUAKE) -VM_localcmd, // #46 void(string s) localcmd (QUAKE) +VM_localcmd_server, // #46 void(string s) localcmd (QUAKE) VM_nextent, // #47 entity(entity e) nextent (QUAKE) VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE) VM_changeyaw, // #49 void() ChangeYaw (QUAKE) @@ -3581,7 +3599,7 @@ NULL, // #396 NULL, // #397 NULL, // #398 NULL, // #399 -// LordHavoc's range #400-#499 +// LadyHavoc's range #400-#499 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY) VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR) VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN) @@ -3823,6 +3841,9 @@ NULL, // #637 NULL, // #638 VM_digest_hex, // #639 NULL, // #640 +NULL, // #641 +VM_coverage, // #642 +NULL, // #643 }; const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);