comparison playerlist.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
comparison
equal deleted inserted replaced
2:fba0b6e6cdc7 3:5a977ccbc7a9
1 /* $Id: playerlist.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
2
3 /*
4 * playerlist.c
5 * modified to sort by teams by Bill Dyess on 9/23/93
6 */
7 #include "copyright.h"
8
9 #include <stdio.h>
10 #include "Wlib.h"
11 #include "defs.h"
12 #include "struct.h"
13 #include "data.h"
14 #include "proto.h"
15 #include "gameconf.h"
16 #include "packets.h"
17
18 /* Prototypes */
19 static void dofulllist P((struct player * pptr, int vpos));
20 /* static char *get_players_rank_name P((struct player *j));*/
21 void getdesig P((struct player * j, char *desig));
22
23 struct teamstruct {
24 short teamnum;
25 short totalnum;
26 short outfitnum;
27 short row;
28 short outfitrow;
29 };
30
31 int lastsortPlayers, lasthnk, lastspl, lastshowDead;
32
33 void
34 playerlist()
35 {
36 int i;
37 char buf[100];
38
39 if (slot == NULL) {
40 if ((slot = (short *) malloc(sizeof(short) * 33)) == NULL) {
41 perror("out of memory?!?\n");
42 exit(-1);
43 }
44 }
45 if (*playerList != 0 && *playerList != ',') { /* do the wide thing
46 [BDyess] */
47 wideplayerlist();
48 return;
49 }
50 for (i = 0; i < 33; i++)
51 slot[i] = -2;
52 lastsortPlayers = sortPlayers;
53 lasthnk = hideNoKills;
54 lastspl = showPreLogins;
55 lastshowDead = showDead;
56
57 W_ClearWindow(playerw);
58
59 (void) strcpy(buf, " Type Rank Name Kills Type Rank Name Kills");
60 W_WriteText(playerw, 0, 1, textColor, buf, strlen(buf), W_RegularFont);
61
62 if (!paradise)
63 (void) strcpy(buf, " Type Rank Name Kills Win Loss Ratio Offense Defense DI");
64 else
65 (void) strcpy(buf, " Type Rank Name Kills Win Loss Ratio Battle Strategy DI");
66
67 W_WriteText(playerw, 0, 20, textColor, buf, strlen(buf), W_RegularFont);
68
69 for (i = 0; i < nplayers; i++)
70 updatePlayer[i] |= ALL_UPDATE;
71
72 playerlist2();
73 }
74
75
76 void
77 playerlist2()
78 {
79 register int i, k, z;
80 char buf[100];
81 short extra = 0, outfitextra = 0;
82 struct teamstruct teams[4];
83 struct teamstruct *quadrant[4], *tempquad; /* topleft, topright,
84 bottomleft, bottomright */
85 register struct player *j;
86 static short sequentialSort = 0;
87 char *rname;
88 char desig[3];
89 short currentSlot;
90 static int usingWide = 0;
91
92 if (*playerList != 0 && *playerList != ',') { /* do the wide thing
93 [BDyess] */
94 if (slot == NULL) {
95 playerlist();
96 return;
97 }
98 wideplayerlist2();
99 usingWide = 1;
100 return;
101 }
102 /* keeps the playerlist from being drawn when not allowed [BDyess] */
103 if (!allowPlayerlist)
104 return;
105
106 if (slot == NULL || lastsortPlayers != sortPlayers ||
107 lasthnk != hideNoKills ||
108 lastspl != showPreLogins ||
109 lastshowDead != showDead ||
110 usingWide) {
111 usingWide = 0;
112 if(resizePlayerList)
113 W_ResizeText(playerw,83,W_WindowHeight(playerw));
114 playerlist();
115 return;
116 }
117 if (!W_IsMapped(playerw))
118 return;
119 if (updatePlayer[me->p_no] & LARGE_UPDATE)
120 dofulllist(me, 21);
121 if (blk_bozolist >= 0)
122 if (updatePlayer[blk_bozolist] & LARGE_UPDATE)
123 dofulllist(&players[blk_bozolist], 22);
124 /*
125 if sortPlayers is on: the players team goes in the top left (top right
126 if robSort: on), the next-largest team in the top right, the third
127 largest in the bottom left, and everything else in the bottom right
128 */
129 if (sortPlayers) {
130 bzero(teams, sizeof(teams));
131 for (i = 0; i < 4; i++)
132 teams[i].teamnum = i;
133 /* figure out how many players on each team */
134 for (i = 0, j = &players[i]; i < nplayers; i++, j++) {
135 if (j->p_status != PFREE && !(j->p_status == POUTFIT && j->p_teami < 0)) {
136 if (j->p_teami < 0 || j->p_teami == number_of_teams) {
137 if (!showDead)
138 continue;
139 extra++;
140 if (j->p_status == POUTFIT && sortOutfitting)
141 outfitextra++;
142 } else if (j->p_teami == number_of_teams) {
143 if (!showPreLogins)
144 continue;
145 extra++;
146 if (j->p_status == POUTFIT && sortOutfitting)
147 outfitextra++;
148 } else {
149 teams[j->p_teami].totalnum++;
150 if (j->p_status == POUTFIT && showDead && sortOutfitting)
151 teams[j->p_teami].outfitnum++;
152 }
153 }
154 /*
155 printf("player %d is on team %d with status %d\n",
156 i,j->p_teami,j->p_status);
157 */
158 }
159
160 for (i = 0; i < 4; i++)
161 quadrant[i] = &teams[i];
162 if (me->p_teami >= 0 && me->p_teami < number_of_teams)
163 teams[me->p_teami].totalnum += 10000;
164 for (i = 3; i > 0; i--) {
165 for (k = 0; k < i; k++) {
166 if (quadrant[k]->totalnum < quadrant[k + 1]->totalnum) {
167 tempquad = quadrant[k];
168 quadrant[k] = quadrant[k + 1];
169 quadrant[k + 1] = tempquad;
170 }
171 }
172 }
173 if (me->p_teami >= 0 && me->p_teami < number_of_teams) {
174 teams[me->p_teami].totalnum -= 10000;
175 if (robsort) {
176 quadrant[0] = quadrant[1];
177 quadrant[1] = &teams[me->p_teami];
178 }
179 }
180 quadrant[3]->totalnum += extra;
181 quadrant[3]->outfitnum += outfitextra;
182
183 if (quadrant[0]->totalnum > 16 || quadrant[1]->totalnum > 16) {
184 /*
185 if one team is so huge as to not fit on just one side, then
186 just list all the players sequentially, but still team sorted.
187 For now, set a flag and clear any freshly empty space.
188 */
189 if (sequentialSort == 0) {
190 sequentialSort = 1;
191 playerlist();
192 return;
193 }
194 quadrant[0]->row = 0;
195 quadrant[1]->row = quadrant[0]->totalnum;
196 quadrant[2]->row = quadrant[1]->row + quadrant[1]->totalnum;
197 quadrant[3]->row = quadrant[2]->row + quadrant[2]->totalnum;
198 /* wipe out the blank sections */
199 for (i = quadrant[3]->row + quadrant[3]->totalnum; i < 32; i++) {
200 if (slot[i] != -1) {
201 /*
202 if we get here, it's not possible to have players
203 blank on the left side
204 */
205 W_ClearArea(playerw, 44, i - 16 + 1, 41, 1);
206 slot[i] = -1;
207 }
208 }
209 } else {
210 if (sequentialSort == 1) {
211 sequentialSort = 0;
212 playerlist();
213 return;
214 }
215 quadrant[0]->row = quadrant[1]->row = 2;
216 if (quadrant[0]->totalnum + quadrant[2]->totalnum <= 16) {
217 quadrant[2]->row = 18 - quadrant[2]->totalnum;
218 } else {
219 quadrant[2]->row = 2 + quadrant[0]->totalnum;
220 quadrant[3]->totalnum += quadrant[0]->totalnum + quadrant[2]->totalnum - 16;
221 }
222 if (quadrant[1]->totalnum + quadrant[3]->totalnum <= 16) {
223 quadrant[3]->row = 18 - quadrant[3]->totalnum;
224 } else {
225 quadrant[3]->row = 2 + quadrant[1]->totalnum;
226 quadrant[2]->row -= quadrant[1]->totalnum + quadrant[3]->totalnum - 16;
227 }
228
229 for (i = 0; i < 4; i++)
230 quadrant[i]->outfitrow = quadrant[i]->row + quadrant[i]->totalnum -
231 quadrant[i]->outfitnum;
232 /* wipe out the blank sections */
233 for (i = 2 + quadrant[0]->totalnum; i < quadrant[2]->row; i++) {
234 if (slot[i - 2] != -1 || players[slot[i - 2]].p_status != POUTFIT) {
235 W_ClearArea(playerw, 0, i, 41, 1);
236 slot[i - 2] = -1;
237 }
238 }
239 for (i = 2 + quadrant[1]->totalnum; i < quadrant[3]->row; i++) {
240 if (slot[16 + i - 2] != -1) {
241 W_ClearArea(playerw, 44, i, 41, 1);
242 slot[16 + i - 2] = -1;
243 }
244 }
245 }
246 }
247 /* update the display for each player */
248 for (i = 0, j = &players[i]; i < nplayers; i++, j++) {
249
250 if (!updatePlayer[i] && !sortPlayers && slot[i] == j->p_no)
251 continue;
252
253 getdesig(j, desig);
254 if (!desig[0]) {
255 if (!sortPlayers)
256 W_ClearArea(playerw, (i > 15) ? 44 : 0, (i > 15) ? i - 16 + 2 : i + 2, 41, 1);
257 continue; /* don't display this guy, he's toast */
258 }
259 rname = get_players_rank_name(j);
260 (void) sprintf(buf, "%c%c %2.2s %-9.9s %-15.15s",
261 teaminfo[j->p_teami].letter,
262 shipnos[j->p_no],
263 desig,
264 rname,
265 j->p_name);
266 /*
267 replace 0.00 kills with spaces if not alive and paradise or not
268 RSA
269 */
270 /* this is optional with the hideNoKills option */
271 if ((j->p_kills <= 0 &&
272 (paradise || RSA_Client <= 0) && hideNoKills)
273 || (j->p_status & ~PALIVE))
274 strcat(buf, " ");
275 else
276 sprintf(buf + strlen(buf), "%6.2f", j->p_kills);
277 if (!sortPlayers) {
278 #ifdef PLPROF
279 printf("Updating player %d\n", j->p_no);
280 #endif /* PLPROF */
281 W_WriteText(playerw, (i > 15) ? 44 : 0,
282 (i > 15) ? i - 16 + 2 : i + 2, playerColor(j), buf,
283 strlen(buf), shipFont(j));
284 slot[i] = j->p_no;
285 } else if (!sequentialSort) {
286 /* find out which quadrant he should be in */
287 for (z = 0; j->p_teami != quadrant[z]->teamnum && z < 3; z++);
288 if (j->p_status == POUTFIT && sortOutfitting)
289 k = quadrant[z]->outfitrow++ - quadrant[z]->row;
290 else
291 k = 0;
292 if (quadrant[z]->row + k > 18) {
293 z += 1;
294 if (z > 3)
295 z -= 2;
296 }
297 currentSlot = (z % 2) * 16 + quadrant[z]->row - 2 + k;
298 if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) {
299 slot[currentSlot] = j->p_no;
300 #ifdef PLPROF
301 printf("Updating %d, currentslot = %d, updatePlayer = %d\n",
302 j->p_no, currentSlot, updatePlayer[j->p_no]);
303 #endif /* PLPROF */
304 W_WriteText(playerw, 44 * (z % 2), k + quadrant[z]->row,
305 playerColor(j), buf, strlen(buf), shipFont(j));
306 }
307 if (!k)
308 quadrant[z]->row++;
309 } else { /* do sequential sort placement */
310 /* find out which quadrant he should be in */
311 for (z = 0; j->p_teami != quadrant[z]->teamnum && z < 3; z++);
312 currentSlot = quadrant[z]->row++;
313 if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) {
314 if (currentSlot >= 16) {
315 W_WriteText(playerw, 44, currentSlot - 16 + 2, playerColor(j),
316 buf, strlen(buf), shipFont(j));
317 } else {
318 W_WriteText(playerw, 0, currentSlot + 2, playerColor(j), buf,
319 strlen(buf), shipFont(j));
320 }
321 }
322 }
323
324 #if 0
325 if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) {
326 slot[currentSlot] = j->p_no;
327 #ifdef PLPROF
328 printf("Updating %d\n", j->p_no);
329 #endif /* PLPROF */
330 W_WriteText(playerw, currentSlot >= 16 ? 44 : 0,
331 currentSlot >= 16 ? currentSlot + 2 - 16 : currentSlot + 2,
332 playerColor(j), buf, strlen(buf), shipFont(j));
333 }
334 }
335 #endif /* 0 */
336 updatePlayer[j->p_no] = NO_UPDATE;
337 }
338 }
339
340 void
341 getdesig(j, desig)
342 struct player *j;
343 char *desig;
344 {
345 switch (j->p_status) {
346 case PALIVE:
347 strncpy(desig, j->p_ship->s_desig, 2);
348 j->p_ship->s_desig[2] = 0;
349 break;
350 case PTQUEUE:
351 strcpy(desig, "tq");
352 break;
353 case POUTFIT:
354 if ((j->p_teami < 0) || !showDead)
355 desig[0] = 0;
356 else
357 strcpy(desig, "--");
358 break;
359 case PEXPLODE:
360 case PDEAD:
361 if (showDead)
362 strcpy(desig, "**");
363 else
364 desig[0] = 0;
365 break;
366 case POBSERVE:
367 strcpy(desig, "ob");
368 break;
369 default:
370 desig[0] = 0;
371 break;
372 }
373 /*
374 if (!*desig) j->p_teami = -1;
375 */
376 if (j->p_teami == number_of_teams && !showPreLogins)
377 desig[0] = 0;
378 }
379
380 static void
381 dofulllist(pptr, vpos)
382 struct player *pptr;
383 int vpos;
384 {
385 char buf[100];
386 char *rname;
387 char desig[3];
388 struct ratings r;
389
390 if (!W_IsMapped(playerw))
391 return;
392
393 getdesig(pptr, desig);
394 if (!desig[0]) {
395 if (pptr->p_no == blk_bozolist)
396 blk_bozolist = -1;
397 W_ClearArea(playerw, 0, vpos, 83, 1);
398 return;
399 }
400 get_ratings(pptr, &r);
401
402 rname = get_players_rank_name(pptr);
403 if (!paradise)
404 sprintf(buf, "%c%c %2.2s %-9.9s %-16.16s%5.2f %5d %5d %6.2f %5.2f %5.2f %8.2f ",
405 teaminfo[pptr->p_teami].letter,
406 shipnos[pptr->p_no],
407 desig /* pptr->p_ship->s_desig */ ,
408 rname,
409 pptr->p_name,
410 pptr->p_kills,
411 r.r_kills,
412 r.r_losses,
413 r.r_ratio,
414 r.r_offrat,
415 r.r_defrat,
416 r.r_di);
417 else
418 sprintf(buf, "%c%c %2.2s %-9.9s %-16.16s%5.2f %5d %5d %6.2f %5.2f %5.2f %8.2f ",
419 teaminfo[pptr->p_teami].letter,
420 shipnos[pptr->p_no],
421 desig /* pptr->p_ship->s_desig */ ,
422 rname,
423 pptr->p_name,
424 pptr->p_kills,
425 r.r_kills,
426 r.r_losses,
427 r.r_ratio,
428 r.r_batrat,
429 r.r_stratrat,
430 r.r_di);
431
432 #ifdef PLPROF
433 printf("Updating %d\n", pptr->p_no);
434 #endif /* PLPROF */
435 W_WriteText(playerw, 0, vpos, playerColor(pptr), buf, strlen(buf),
436 shipFont(pptr));
437 }
438
439 char *
440 get_players_rank_name(j)
441 struct player *j;
442 {
443 char *r;
444 if (j->p_stats.st_rank < 0)
445 j->p_stats.st_rank = 0;
446 if (!paradise) {
447 r = ranks[j->p_stats.st_rank].name;
448 } else {
449 if (j->p_stats2.st_royal == 0)
450 r = ranks2[j->p_stats2.st_rank].name;
451 else
452 r = royal[j->p_stats2.st_royal].name;
453 }
454 return (r);
455 }
456
457 void
458 playerwEvent(data)
459 W_Event *data;
460 {
461 int key;
462 struct obtype *target;
463
464 key = doKeymap(data);
465 if (key == -1)
466 return;
467 switch (key) {
468 case 'l': /* lock on [BDyess] */
469 target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
470 sendPlaylockReq(target->o_num);
471 me->p_playerl = target->o_num;
472 break;
473 case 'i':
474 case 'I':
475 if (!infomapped)
476 inform(data->Window, data->x, data->y, key);
477 else
478 destroyInfo();
479 break;
480 case 'X':
481 macroState = 1;
482 warning("Macro mode");
483 break;
484 default:
485 warning("Invalid key");
486 }
487 }
488
489 void
490 selectblkbozo(data)
491 W_Event *data;
492 {
493 int width, slotnum;
494
495 if (*playerList
496 && *playerList != ',')
497 return;
498 width = W_WindowWidth(data->Window);
499 if (data->key == W_RBUTTON || data->key == W_LBUTTON || data->key == W_MBUTTON)
500 if (data->y > W_Textheight * 2 + 1 && data->y < W_Textheight * 19) {
501 W_TranslatePoints(data->Window, &data->x, &data->y);
502 slotnum = 0;
503 if (data->x > width / 2)
504 slotnum += 16;
505 /* only look for players in the slotspace */
506 if (data->y <= (16 + 1)) {
507 slotnum += data->y - 2;
508 if (slot[slotnum] != me->p_no)
509 blk_bozolist = slot[slotnum];
510 if (blk_bozolist >= 0) {
511 updatePlayer[blk_bozolist] |= LARGE_UPDATE;
512 } else {
513 blk_bozolist = -1;
514 W_ClearArea(playerw, 0, 22, 83, 1);
515 }
516 }
517 }
518 }