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