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