]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/antilag.qc
Antilag: fix vehicles and monsters
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / antilag.qc
1 #if defined(CSQC)
2 #elif defined(MENUQC)
3 #elif defined(SVQC)
4     #include <common/state.qh>
5     #include <common/vehicles/all.qh>
6     #include "antilag.qh"
7 #endif
8
9 const int ANTILAG_MAX_ORIGINS = 64;
10 .vector antilag_origins[ANTILAG_MAX_ORIGINS];
11 .float antilag_times[ANTILAG_MAX_ORIGINS];
12 .int antilag_index;
13 .vector antilag_saved_origin;
14 .float antilag_takenback;
15
16 .float antilag_debug;
17
18 void antilag_record(entity e, entity store, float t)
19 {
20     if (e.vehicle) {
21         if (e.vehicle.vehicle_flags == VHF_PLAYERSLOT) return;
22         antilag_record(e.vehicle, e.vehicle, t);
23     }
24
25         if (time < store.antilag_times[store.antilag_index]) return;
26         store.antilag_index += 1;
27         if (store.antilag_index >= ANTILAG_MAX_ORIGINS)
28                 store.antilag_index = 0;
29         store.antilag_times[store.antilag_index] = t;
30         store.antilag_origins[store.antilag_index] = e.origin;
31
32         if (store.antilag_debug)
33                 te_spark(antilag_takebackorigin(e, store, t - store.antilag_debug), '0 0 0', 32);
34 }
35
36 // finds the index BEFORE t
37 float antilag_find(entity e, entity store, float t)
38 {
39         for(int i = store.antilag_index; i > 0; --i)
40                 if(store.antilag_times[i] >= t)
41                         if(store.antilag_times[i - 1] < t)
42                                 return i - 1;
43
44         if(store.antilag_times[0] >= t)
45                 if(store.antilag_times[ANTILAG_MAX_ORIGINS - 1] < t)
46                         return ANTILAG_MAX_ORIGINS - 1;
47
48         for(int i = ANTILAG_MAX_ORIGINS - 1; i > store.antilag_index + 1; --i)
49                 if(store.antilag_times[i] >= t)
50                         if(store.antilag_times[i - 1] < t)
51                                 return i - 1;
52
53         // if we get here, t is sandwiched nowhere, so let's assume it's in the present
54         return -1;
55 }
56
57 vector antilag_takebackorigin(entity e, entity store, float t)
58 {
59         int i0 = antilag_find(e, store, t);
60         if (i0 < 0)
61         {
62                 // IN THE PRESENT
63                 if(store.antilag_takenback)
64                         return store.antilag_saved_origin;
65                 else
66                         return e.origin;
67         }
68         int i1 = i0 + 1;
69         if (i1 >= ANTILAG_MAX_ORIGINS)
70                 i1 = 0;
71
72         return lerpv(store.antilag_times[i0], store.antilag_origins[i0], store.antilag_times[i1], store.antilag_origins[i1], t);
73 }
74
75 vector antilag_takebackavgvelocity(entity e, entity store, float t0, float t1)
76 {
77         if (t0 >= t1) return '0 0 0';
78         vector o0 = antilag_takebackorigin(e, store, t0);
79         vector o1 = antilag_takebackorigin(e, store, t1);
80         return (o1 - o0) * (1 / (t1 - t0));
81 }
82
83 void antilag_takeback(entity e, entity store, float t)
84 {
85         if (e.vehicle) {
86             if (e.vehicle.vehicle_flags == VHF_PLAYERSLOT) return;
87                 antilag_takeback(e.vehicle, store, t);
88     }
89
90         if (!store.antilag_takenback)
91                 store.antilag_saved_origin = e.origin;
92
93         vector org = antilag_takebackorigin(e, store, t);
94         setorigin(e, org);
95         store.antilag_takenback = true;
96 }
97
98 void antilag_restore(entity e, entity store)
99 {
100         if (e.vehicle) {
101             if (e.vehicle.vehicle_flags == VHF_PLAYERSLOT) return;
102                 antilag_restore(e.vehicle, e.vehicle);
103         }
104
105         if (!store.antilag_takenback) return;
106
107         setorigin(e, store.antilag_saved_origin);
108         store.antilag_takenback = false;
109 }
110
111 void antilag_clear(entity e, entity store)
112 {
113         antilag_restore(e, store);
114         for (int i = 0; i < ANTILAG_MAX_ORIGINS; ++i) {
115                 store.antilag_times[i] = -2342;
116                 store.antilag_origins[i] = e.origin;
117         }
118         store.antilag_index = ANTILAG_MAX_ORIGINS - 1; // next one is 0
119 }