]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/scores.qc
add ClearAll
[divverent/nexuiz.git] / data / qcsrc / server / scores.qc
1 .float scores[MAX_SCORE];
2 .float teamscores[MAX_TEAMSCORE];
3
4 .entity scorekeeper;
5 entity teamscorekeepers[16];
6 string scores_label[MAX_SCORE];
7 float scores_flags[MAX_SCORE];
8 string teamscores_label[MAX_TEAMSCORE];
9 float teamscores_flags[MAX_TEAMSCORE];
10 float teamscores_entities_count;
11 var .float scores_primary;
12 var .float teamscores_primary;
13
14 .float Version;
15 .float(entity to) SendEntity;
16
17 vector ScoreField_Compare(entity t1, entity t2, .float field, float fieldflags, vector previous) // returns: cmp value, best prio
18 {
19         if(fieldflags & SFL_SORT_PRIO_MASK < previous_y)
20                 return previous;
21         if(t1.field == t2.field)
22                 return previous;
23
24         previous_y = fieldflags & SFL_SORT_PRIO_MASK;
25
26         if(fieldflags & SFL_DECREASING)
27                 previous_x = (t1.field - t2.field);
28         else
29                 previous_x = (t2.field - t1.field);
30
31         return previous;
32 }
33
34 /*
35  * teamscore entities
36  */
37
38 void TeamScore_SendEntity(entity to)
39 {
40         float i;
41
42         WriteByte(MSG_ENTITY, ENT_CLIENT_TEAMSCORES);
43         WriteByte(MSG_ENTITY, self.team);
44         for(i = 0; i < MAX_TEAMSCORE; ++i)
45                 WriteShort(MSG_ENTITY, self.teamscores[i]);
46 }
47
48 void TeamScore_Spawn(float t, string name)
49 {
50         entity ts;
51         ts = spawn();
52         ts.classname = "csqc_score_team";
53         ts.SendEntity = TeamScore_SendEntity;
54         ts.netname = name; // not used yet, FIXME
55         ts.Version = 1; // immediately send, so csqc knows about the team
56         teamscorekeepers[t] = ts;
57         ++teamscores_entities_count;
58 }
59
60 void TeamScore_Add(entity player, float scorefield, float score)
61 {
62         entity s;
63         s = teamscorekeepers[player.team];
64         if(!s)
65                 error("Adding score to unknown team!");
66         s.(teamscores[scorefield]) += score;
67         s.Version += 1;
68 }
69
70 float TeamScore_Compare(entity t1, entity t2)
71 {
72         if(!t1 || !t2) return (!t2) - !t1;
73
74         vector result;
75         float i;
76         for(i = 0; i < MAX_TEAMSCORE; ++i)
77                 result = ScoreField_Compare(t1, t2, teamscores[i], teamscores_flags[i], result);
78         return result_x;
79 }
80
81 /*
82  * the scoreinfo entity
83  */
84
85 void ScoreInfo_SetLabel_PlayerScore(float i, string label, float scoreflags)
86 {
87         scores_label[i] = label;
88         scores_flags[i] = scoreflags;
89         if(scoreflags & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY)
90                 scores_primary = scores[i];
91 }
92
93 void ScoreInfo_SetLabel_TeamScore(float i, string label, float scoreflags)
94 {
95         teamscores_label[i] = label;
96         teamscores_flags[i] = scoreflags;
97         if(scoreflags & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY)
98                 teamscores_primary = teamscores[i];
99 }
100
101 void ScoreInfo_SendEntity(entity to)
102 {
103         WriteByte(MSG_ENTITY, ENT_CLIENT_SCORES_INFO);
104         float i;
105         for(i = 0; i < MAX_SCORE; ++i)
106         {
107                 WriteString(MSG_ENTITY, scores_label[i]);
108                 WriteByte(MSG_ENTITY, scores_flags[i]);
109         }
110         for(i = 0; i < MAX_TEAMSCORE; ++i)
111         {
112                 WriteString(MSG_ENTITY, teamscores_label[i]);
113                 WriteByte(MSG_ENTITY, teamscores_flags[i]);
114         }
115 }
116
117 void ScoreInfo_Init(float teams)
118 {
119         if(teams >= 1)
120                 TeamScore_Spawn(COLOR_TEAM1, "Red");
121         if(teams >= 2)
122                 TeamScore_Spawn(COLOR_TEAM2, "Blue");
123         if(teams >= 3)
124                 TeamScore_Spawn(COLOR_TEAM3, "Yellow");
125         if(teams >= 4)
126                 TeamScore_Spawn(COLOR_TEAM4, "Pink");
127         entity si;
128         si = spawn();
129         si.classname = "csqc_score_info";
130         si.SendEntity = ScoreInfo_SendEntity;
131         si.Version = 1;
132 }
133
134 /*
135  * per-player score entities
136  */
137
138 void PlayerScore_SendEntity()
139 {
140         float i;
141
142         WriteByte(MSG_ENTITY, ENT_CLIENT_SCORES);
143         WriteByte(MSG_ENTITY, num_for_edict(self.owner));
144         for(i = 0; i < MAX_SCORE; ++i)
145                 WriteShort(MSG_ENTITY, self.scores[i]);
146 }
147
148 void PlayerScore_Clear(entity player)
149 {
150         entity sk;
151         float i;
152
153         if(!teamscores_entities_count)
154         {
155                 sk = player.scorekeeper;
156                 for(i = 0; i < MAX_SCORE; ++i)
157                         sk.(scores[i]) = 0;
158                 sk.Version += 1;
159         }
160 }
161
162 void Score_ClearAll()
163 {
164         entity p, sk;
165         float i;
166         FOR_EACH_CLIENTSLOT(p)
167         {
168                 sk = p.scorekeeper;
169                 if(!sk)
170                         continue;
171                 for(i = 0; i < MAX_SCORE; ++i)
172                         sk.(scores[i]) = 0;
173                 sk.Version += 1;
174         }
175         for(i = 0; i < 16; ++i)
176         {
177                 sk = teamscorekeepers[i];
178                 if(!sk)
179                         continue;
180                 for(i = 0; i < MAX_SCORE; ++i)
181                         sk.(teamscores[i]) = 0;
182                 sk.Version += 1;
183         }
184 }
185
186 void PlayerScore_Attach(entity player)
187 {
188         entity sk;
189         if(player.scorekeeper)
190                 error("player already has a scorekeeper");
191         sk = spawn();
192         sk.owner = player;
193         sk.SendEntity = PlayerScore_SendEntity;
194         player.scorekeeper = sk;
195 }
196
197 void PlayerScore_Detach(entity player)
198 {
199         if(!player.scorekeeper)
200                 error("player has no scorekeeper");
201         remove(player.scorekeeper);
202         player.scorekeeper = world;
203 }
204
205 void PlayerScore_Add(entity player, float scorefield, float score)
206 {
207         entity s;
208         s = player.scorekeeper;
209         if(!s)
210                 error("Adding score to unknown player!");
211         s.(scores[scorefield]) += score;
212         s.Version += 1;
213 }
214
215 float PlayerScore_Compare(entity t1, entity t2)
216 {
217         if(!t1 || !t2) return (!t2) - !t1;
218
219         vector result;
220         float i;
221         for(i = 0; i < MAX_TEAMSCORE; ++i)
222                 result = ScoreField_Compare(t1, t2, scores[i], scores_flags[i], result);
223         return result_x;
224 }
225
226 void WinningConditionHelper()
227 {
228         float c;
229         if(teamscores_entities_count)
230         {
231                 float t;
232                 WinningConditionHelper_equality = 1;
233                 WinningConditionHelper_winnerteam = 0;
234                 for(t = 1; t < 16; ++t)
235                 {
236                         c = TeamScore_Compare(teamscorekeepers[WinningConditionHelper_winnerteam], teamscorekeepers[t]);
237                         if(c == 0)
238                                 WinningConditionHelper_equality = 1;
239                         else if(c < 0)
240                         {
241                                 WinningConditionHelper_equality = 0;
242                                 WinningConditionHelper_winnerteam = t;
243                         }
244                 }
245
246                 WinningConditionHelper_topscore = teamscorekeepers[WinningConditionHelper_winnerteam].teamscores_primary;
247
248                 WinningConditionHelper_winner = world;
249                 if(WinningConditionHelper_equality)
250                         WinningConditionHelper_winnerteam = -1;
251         }
252         else
253         {
254                 entity p;
255                 WinningConditionHelper_equality = 1;
256                 WinningConditionHelper_winner = world;
257                 FOR_EACH_PLAYER(p)
258                 {
259                         c = PlayerScore_Compare(WinningConditionHelper_winner.scorekeeper, p.scorekeeper);
260                         if(c == 0)
261                                 WinningConditionHelper_equality = 1;
262                         else if(c < 0)
263                         {
264                                 WinningConditionHelper_equality = 0;
265                                 WinningConditionHelper_winner = p;
266                         }
267                 }
268
269                 WinningConditionHelper_topscore = WinningConditionHelper_winner.scorekeeper.scores_primary;
270
271                 if(WinningConditionHelper_equality)
272                         WinningConditionHelper_winner = world;
273                 WinningConditionHelper_winnerteam = -1;
274         }
275 }