X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fantilag.qc;h=93ca6acf93eba5b7204c3dd0d4353a5b4a9901dd;hp=c51d3cf5ba536d01e5237da5fb2fe069adc5891a;hb=d8e73f411f306e6d475bf385bfe5777692aee4a0;hpb=4c7352309564fc88b28216e0aa9ac509ce4d3dc6 diff --git a/qcsrc/server/antilag.qc b/qcsrc/server/antilag.qc index c51d3cf5b..93ca6acf9 100644 --- a/qcsrc/server/antilag.qc +++ b/qcsrc/server/antilag.qc @@ -1,9 +1,11 @@ +#include "antilag.qh" #if defined(CSQC) #elif defined(MENUQC) #elif defined(SVQC) - #include "../dpdefs/progsdefs.qh" - #include "../dpdefs/dpextensions.qh" - #include "../common/vehicles/all.qh" + #include + #include + #include + #include #include "antilag.qh" #endif @@ -16,61 +18,53 @@ const int ANTILAG_MAX_ORIGINS = 64; .float antilag_debug; -void antilag_record(entity e, float t) +void antilag_record(entity e, entity store, float t) { - if (e.vehicle && e.vehicle.vehicle_flags == VHF_PLAYERSLOT) - return; - - if(e.vehicle) - antilag_record(e.vehicle, t); - - if(time < e.(antilag_times[e.antilag_index])) - return; - e.antilag_index = e.antilag_index + 1; - if(e.antilag_index >= ANTILAG_MAX_ORIGINS) - e.antilag_index = 0; - e.(antilag_times[e.antilag_index]) = t; - e.(antilag_origins[e.antilag_index]) = e.origin; - - if(e.antilag_debug) - te_spark(antilag_takebackorigin(e, t - e.antilag_debug), '0 0 0', 32); - + if (e.vehicle) { + if (e.vehicle.vehicle_flags == VHF_PLAYERSLOT) return; + antilag_record(e.vehicle, e.vehicle, t); + } + + if (time < store.antilag_times[store.antilag_index]) return; + store.antilag_index += 1; + if (store.antilag_index >= ANTILAG_MAX_ORIGINS) + store.antilag_index = 0; + store.antilag_times[store.antilag_index] = t; + store.antilag_origins[store.antilag_index] = e.origin; + + if (store.antilag_debug) + te_spark(antilag_takebackorigin(e, store, t - store.antilag_debug), '0 0 0', 32); } // finds the index BEFORE t -float antilag_find(entity e, float t) +float antilag_find(entity e, entity store, float t) { - for(int i = e.antilag_index; i > 0; --i) - if(e.(antilag_times[i]) >= t) - if(e.(antilag_times[i - 1]) < t) + for(int i = store.antilag_index; i > 0; --i) + if(store.antilag_times[i] >= t) + if(store.antilag_times[i - 1] < t) return i - 1; - if(e.(antilag_times[0]) >= t) - if(e.(antilag_times[ANTILAG_MAX_ORIGINS - 1]) < t) + if(store.antilag_times[0] >= t) + if(store.antilag_times[ANTILAG_MAX_ORIGINS - 1] < t) return ANTILAG_MAX_ORIGINS - 1; - for(int i = ANTILAG_MAX_ORIGINS - 1; i > e.antilag_index + 1; --i) - if(e.(antilag_times[i]) >= t) - if(e.(antilag_times[i - 1]) < t) + for(int i = ANTILAG_MAX_ORIGINS - 1; i > store.antilag_index + 1; --i) + if(store.antilag_times[i] >= t) + if(store.antilag_times[i - 1] < t) return i - 1; // if we get here, t is sandwiched nowhere, so let's assume it's in the present return -1; } -vector lerpv(float t0, vector v0, float t1, vector v1, float t) -{ - return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); -} - -vector antilag_takebackorigin(entity e, float t) +vector antilag_takebackorigin(entity e, entity store, float t) { - int i0 = antilag_find(e, t); + int i0 = antilag_find(e, store, t); if (i0 < 0) { // IN THE PRESENT - if(e.antilag_takenback) - return e.antilag_saved_origin; + if(store.antilag_takenback) + return store.antilag_saved_origin; else return e.origin; } @@ -78,58 +72,163 @@ vector antilag_takebackorigin(entity e, float t) if (i1 >= ANTILAG_MAX_ORIGINS) i1 = 0; - return lerpv(e.(antilag_times[i0]), e.(antilag_origins[i0]), e.(antilag_times[i1]), e.(antilag_origins[i1]), t); + return lerpv(store.antilag_times[i0], store.antilag_origins[i0], store.antilag_times[i1], store.antilag_origins[i1], t); } -vector antilag_takebackavgvelocity(entity e, float t0, float t1) +vector antilag_takebackavgvelocity(entity e, entity store, float t0, float t1) { - vector o0, o1; - - if(t0 >= t1) - return '0 0 0'; - o0 = antilag_takebackorigin(e, t0); - o1 = antilag_takebackorigin(e, t1); + if (t0 >= t1) return '0 0 0'; + vector o0 = antilag_takebackorigin(e, store, t0); + vector o1 = antilag_takebackorigin(e, store, t1); return (o1 - o0) * (1 / (t1 - t0)); } -void antilag_takeback(entity e, float t) +void antilag_takeback(entity e, entity store, float t) { + if (e.vehicle) { + if (e.vehicle.vehicle_flags == VHF_PLAYERSLOT) return; + antilag_takeback(e.vehicle, e.vehicle, t); + } - if (e.vehicle && e.vehicle.vehicle_flags == VHF_PLAYERSLOT) - return; + if (!store.antilag_takenback) + store.antilag_saved_origin = e.origin; + + vector org = antilag_takebackorigin(e, store, t); + setorigin(e, org); + store.antilag_takenback = true; +} - if(e.vehicle) - antilag_takeback(e.vehicle, t); +void antilag_restore(entity e, entity store) +{ + if (e.vehicle) { + if (e.vehicle.vehicle_flags == VHF_PLAYERSLOT) return; + antilag_restore(e.vehicle, e.vehicle); + } - if(!e.antilag_takenback) - e.antilag_saved_origin = e.origin; + if (!store.antilag_takenback) return; - setorigin(e, antilag_takebackorigin(e, t)); - e.antilag_takenback = true; + setorigin(e, store.antilag_saved_origin); + store.antilag_takenback = false; } -void antilag_restore(entity e) +void antilag_clear(entity e, entity store) { - if (e.vehicle && e.vehicle.vehicle_flags == VHF_PLAYERSLOT) - return; + antilag_restore(e, store); + for (int i = 0; i < ANTILAG_MAX_ORIGINS; ++i) { + store.antilag_times[i] = -2342; + store.antilag_origins[i] = e.origin; + } + store.antilag_index = ANTILAG_MAX_ORIGINS - 1; // next one is 0 +} - if(e.vehicle) - antilag_restore(e.vehicle); +// TODO: use a single intrusive list across all antilagged entities +void antilag_takeback_all(entity ignore, float lag) +{ + FOREACH_CLIENT(IS_PLAYER(it) && it != ignore, antilag_takeback(it, CS(it), time - lag)); + IL_EACH(g_monsters, it != ignore, + { + antilag_takeback(it, it, time - lag); + }); + IL_EACH(g_projectiles, it != ignore && it.classname == "nade", + { + antilag_takeback(it, it, time - lag); + }); +} - if(!e.antilag_takenback) - return; +void antilag_restore_all(entity ignore) +{ + FOREACH_CLIENT(IS_PLAYER(it) && it != ignore, antilag_restore(it, CS(it))); + IL_EACH(g_monsters, it != ignore, + { + antilag_restore(it, it); + }); + IL_EACH(g_projectiles, it != ignore && it.classname == "nade", + { + antilag_restore(it, it); + }); +} - setorigin(e, e.antilag_saved_origin); - e.antilag_takenback = false; +float antilag_getlag(entity e) +{ + float lag = ((IS_REAL_CLIENT(e)) ? ANTILAG_LATENCY(e) : 0); + bool noantilag = ((IS_CLIENT(e)) ? CS(e).cvar_cl_noantilag : false); + if(autocvar_g_antilag == 0 || noantilag || lag < 0.001) + lag = 0; + + return lag; } -void antilag_clear(entity e) +/* +================== +traceline_antilag + +A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE things with a trace attack +Additionally it moves players back into the past before the trace and restores them afterward. +================== +*/ +void tracebox_antilag_force_wz (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag, float wz) { - antilag_restore(e); - for (int i = 0; i < ANTILAG_MAX_ORIGINS; ++i) - { - e.(antilag_times[i]) = -2342; - e.(antilag_origins[i]) = e.origin; - } - e.antilag_index = ANTILAG_MAX_ORIGINS - 1; // next one is 0 + // check whether antilagged traces are enabled + if (lag < 0.001) + lag = 0; + if (!IS_REAL_CLIENT(forent)) + lag = 0; // only antilag for clients + + // change shooter to SOLID_BBOX so the shot can hit corpses + int oldsolid = source.dphitcontentsmask; + if(source) + source.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; + + if (lag) + antilag_takeback_all(forent, lag); + + // do the trace + if(wz) + WarpZone_TraceBox (v1, mi, ma, v2, nomonst, forent); + else + tracebox (v1, mi, ma, v2, nomonst, forent); + + // restore players to current positions + if (lag) + antilag_restore_all(forent); + + // restore shooter solid type + if(source) + source.dphitcontentsmask = oldsolid; +} +void traceline_antilag_force (entity source, vector v1, vector v2, float nomonst, entity forent, float lag) +{ + tracebox_antilag_force_wz(source, v1, '0 0 0', '0 0 0', v2, nomonst, forent, lag, false); +} +void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag) +{ + bool noantilag = ((IS_CLIENT(source)) ? CS(source).cvar_cl_noantilag : false); + if (autocvar_g_antilag != 2 || noantilag) + lag = 0; + traceline_antilag_force(source, v1, v2, nomonst, forent, lag); +} +void tracebox_antilag (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag) +{ + bool noantilag = ((IS_CLIENT(source)) ? CS(source).cvar_cl_noantilag : false); + if (autocvar_g_antilag != 2 || noantilag) + lag = 0; + tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, false); +} +void WarpZone_traceline_antilag_force (entity source, vector v1, vector v2, float nomonst, entity forent, float lag) +{ + tracebox_antilag_force_wz(source, v1, '0 0 0', '0 0 0', v2, nomonst, forent, lag, true); +} +void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag) +{ + bool noantilag = ((IS_CLIENT(source)) ? CS(source).cvar_cl_noantilag : false); + if (autocvar_g_antilag != 2 || noantilag) + lag = 0; + WarpZone_traceline_antilag_force(source, v1, v2, nomonst, forent, lag); +} +void WarpZone_tracebox_antilag (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag) +{ + bool noantilag = ((IS_CLIENT(source)) ? CS(source).cvar_cl_noantilag : false); + if (autocvar_g_antilag != 2 || noantilag) + lag = 0; + tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, true); }