]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/accuracy.qc
add frags per weapon into playerstats (e acc-weapon-frags)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / accuracy.qc
1 .float accuracy_hit[WEP_MAXCOUNT];
2 .float accuracy_fired[WEP_MAXCOUNT];
3 .float accuracy_cnt_hit[WEP_MAXCOUNT];
4 .float accuracy_cnt_fired[WEP_MAXCOUNT];
5 FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(accuracy_hit);
6 FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(accuracy_fired);
7 FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(accuracy_cnt_hit);
8 FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(accuracy_cnt_fired);
9
10 float accuracy_byte(float n, float d)
11 {
12         //print(sprintf("accuracy: %d / %d\n", n, d));
13         if(n <= 0)
14                 return 0;
15         if(n > d)
16                 return 255;
17         return 1 + rint(n * 100.0 / d);
18 }
19
20 float accuracy_send(entity to, float sf)
21 {
22         float w, f;
23         entity a;
24         WriteByte(MSG_ENTITY, ENT_CLIENT_ACCURACY);
25
26         a = self.owner;
27         if(a.classname == "spectator")
28                 a = a.enemy;
29         a = a.accuracy;
30
31         if(to != a.owner)
32                 if not(self.owner.cvar_cl_accuracy_data_share && autocvar_sv_accuracy_data_share)
33                         sf = 0;
34         // note: zero sendflags can never be sent... so we can use that to say that we send no accuracy!
35         WriteInt24_t(MSG_ENTITY, sf);
36         if(sf == 0)
37                 return TRUE;
38         // note: we know that client and server agree about SendFlags...
39         for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w, f *= 2)
40         {
41                 if(sf & f)
42                         WriteByte(MSG_ENTITY, accuracy_byte(self.(accuracy_hit[w]), self.(accuracy_fired[w])));
43         }
44         return TRUE;
45 }
46
47 // init/free
48 void accuracy_init(entity e)
49 {
50         e.accuracy = spawn();
51         e.accuracy.owner = e;
52         e.accuracy.classname = "accuracy";
53         e.accuracy.drawonlytoclient = e;
54         Net_LinkEntity(e.accuracy, FALSE, 0, accuracy_send);
55 }
56
57 void accuracy_free(entity e)
58 {
59         remove(e.accuracy);
60 }
61
62 // force a resend of a player's accuracy stats
63 void accuracy_resend(entity e)
64 {
65         e.accuracy.SendFlags = 0xFFFFFF;
66 }
67
68 // update accuracy stats
69 void accuracy_set(entity e, float w, float fired, float hit)
70 {
71         entity a;
72         float b;
73         a = e.accuracy;
74         if(!a)
75                 return;
76         w -= WEP_FIRST;
77         b = accuracy_byte(a.(accuracy_hit[w]), a.(accuracy_fired[w]));
78         a.(accuracy_hit[w]) = hit;
79         a.(accuracy_fired[w]) = fired;
80
81     if(hit)
82         a.(accuracy_cnt_hit[w]) = 1;
83         a.(accuracy_cnt_fired[w]) = 1;
84
85         if(b == accuracy_byte(hit, fired))
86                 return;
87         w = pow(2, w);
88         a.SendFlags |= w;
89         FOR_EACH_CLIENT(a)
90                 if(a.classname == "spectator")
91                         if(a.enemy == e)
92                                 a.SendFlags |= w;
93 }
94
95 void accuracy_add(entity e, float w, float fired, float hit)
96 {
97         entity a;
98         float b;
99         a = e.accuracy;
100         if(!a || !(hit || fired))
101                 return;
102         w -= WEP_FIRST;
103         b = accuracy_byte(a.(accuracy_hit[w]), a.(accuracy_fired[w]));
104         if(hit)
105                 a.(accuracy_hit[w]) += hit;
106         if(fired)
107                 a.(accuracy_fired[w]) += fired;
108
109     if(hit)
110         a.(accuracy_cnt_hit[w]) += 1;
111         a.(accuracy_cnt_fired[w]) += 1;
112
113         if(b == accuracy_byte(a.(accuracy_hit[w]), a.(accuracy_fired[w])))
114                 return;
115         w = pow(2, w);
116         a.SendFlags |= w;
117         FOR_EACH_CLIENT(a)
118                 if(a.classname == "spectator")
119                         if(a.enemy == e)
120                                 a.SendFlags |= w;
121 }
122
123 float accuracy_isgooddamage(entity attacker, entity targ)
124 {
125         if(!inWarmupStage)
126         if(targ.flags & FL_CLIENT)
127         if(targ.deadflag == DEAD_NO)
128         if(IsDifferentTeam(attacker, targ))
129                 return TRUE;
130         return FALSE;
131 }
132
133 float accuracy_canbegooddamage(entity attacker)
134 {
135         if(!inWarmupStage)
136                 return TRUE;
137         return FALSE;
138 }