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