]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/weapons/hitplot.qc
take3: format 903 files
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / hitplot.qc
1 #include "hitplot.qh"
2
3 #include <server/defs.qh>
4 #include <server/miscfunctions.qh>
5 #include "../antilag.qh"
6 #include "../g_subs.qh"
7 #include <common/weapons/_all.qh>
8 #include <common/state.qh>
9 #include <common/wepent.qh>
10
11 vector W_HitPlotUnnormalizedUntransform(vector screenforward, vector screenright, vector screenup, vector v)
12 {
13         vector ret;
14         ret.x = screenright * v;
15         ret.y = screenup * v;
16         ret.z = screenforward * v;
17         return ret;
18 }
19
20 vector W_HitPlotNormalizedUntransform(vector org, entity targ, vector screenforward, vector screenright, vector screenup, vector v)
21 {
22         float i, j, k;
23         vector mi, ma, thisv, myv, ret;
24
25         myv = W_HitPlotUnnormalizedUntransform(screenforward, screenright, screenup, org);
26
27         // x = 0..1 relative to hitbox; y = 0..1 relative to hitbox; z = distance
28
29         mi = ma = targ.origin + 0.5 * (targ.mins + targ.maxs);
30         for (i = 0; i < 2; ++i) {
31                 for (j = 0; j < 2; ++j) {
32                         for (k = 0; k < 2; ++k) {
33                                 thisv = targ.origin;
34                                 if (i) { thisv.x += targ.maxs.x; } else { thisv.x += targ.mins.x; }
35                                 if (j) { thisv.y += targ.maxs.y; } else { thisv.y += targ.mins.y; }
36                                 if (k) { thisv.z += targ.maxs.z; } else { thisv.z += targ.mins.z; }
37                                 thisv = W_HitPlotUnnormalizedUntransform(screenforward, screenright, screenup, thisv);
38                                 if (i || j || k) {
39                                         if (mi.x > thisv.x) { mi.x = thisv.x; } if (ma.x < thisv.x) { ma.x = thisv.x; }
40                                         if (mi.y > thisv.y) { mi.y = thisv.y; } if (ma.y < thisv.y) { ma.y = thisv.y; }
41                                         // if(mi_z > thisv_z) mi_z = thisv_z; if(ma_z < thisv_z) ma_y = thisv_z;
42                                 } else {
43                                         // first run
44                                         mi = ma = thisv;
45                                 }
46                         }
47                 }
48         }
49
50         thisv = W_HitPlotUnnormalizedUntransform(screenforward, screenright, screenup, v);
51         ret.x = (thisv.x - mi.x) / (ma.x - mi.x);
52         ret.y = (thisv.y - mi.y) / (ma.y - mi.y);
53         ret.z = thisv.z - myv.z;
54         return ret;
55 }
56
57 void W_HitPlotAnalysis(entity player, .entity weaponentity, vector screenforward, vector screenright, vector screenup)
58 {
59         if (CS(player).hitplotfh >= 0) {
60                 float lag = ANTILAG_LATENCY(player);
61                 if (lag < 0.001) {
62                         lag = 0;
63                 }
64                 if (!IS_REAL_CLIENT(player)) {
65                         lag = 0; // only antilag for clients
66                 }
67                 vector org = player.origin + player.view_ofs;
68                 traceline_antilag_force(player, org, org + screenforward * max_shot_distance, MOVE_NORMAL, player, lag);
69                 if (IS_CLIENT(trace_ent) || IS_MONSTER(trace_ent)) {
70                         entity store = IS_CLIENT(trace_ent) ? CS(trace_ent) : trace_ent;
71                         antilag_takeback(trace_ent, store, time - lag);
72                         vector hitplot = W_HitPlotNormalizedUntransform(org, trace_ent, screenforward, screenright, screenup, trace_endpos);
73                         antilag_restore(trace_ent, store);
74                         fputs(CS(player).hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(player.(weaponentity).m_switchweapon.m_id), "\n"));
75                         // print(strcat(ftos(hitplot_x), " ", ftos(hitplot_y), " ", ftos(hitplot_z), "\n"));
76                 }
77         }
78 }
79
80 void W_HitPlotOpen(entity player)
81 {
82         if (autocvar_g_hitplots || strhasword(autocvar_g_hitplots_individuals, player.netaddress)) {
83                 CS(player).hitplotfh = fopen(strcat("hits-", matchid, "-", player.netaddress, "-", ftos(player.playerid), ".plot"), FILE_WRITE);
84                 fputs(CS(player).hitplotfh, strcat("#name ", playername(player, false), "\n"));
85         } else { CS(player).hitplotfh = -1; }
86 }
87
88 void W_HitPlotClose(entity player)
89 {
90         if (CS(player).hitplotfh >= 0) {
91                 fclose(CS(player).hitplotfh);
92                 CS(player).hitplotfh = -1;
93         }
94 }