ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_party.C
Revision: 1.15
Committed: Mon Jan 15 21:06:20 2007 UTC (17 years, 4 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.14: +22 -22 lines
Log Message:
comments

File Contents

# Content
1 /*
2 * CrossFire, A Multiplayer game for X-windows
3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
23 */
24
25 #include <global.h>
26 #include <sproto.h>
27 #include <spells.h>
28
29 #ifdef COZY_SERVER
30 // used for pet monster logic etc.
31 int
32 same_party (partylist *a, partylist *b)
33 {
34 return a == b && a;
35 }
36 #endif
37
38 static partylist *firstparty = NULL; /* Keeps track of first party in list */
39 static partylist *lastparty = NULL; /*Keeps track of last party in list */
40
41 partylist *
42 get_firstparty (void)
43 {
44 return firstparty;
45 }
46
47 void remove_party (partylist *target_party);
48
49 /* Forms the party struct for a party called 'params'. it is the responsibility
50 * of the caller to ensure that the name is unique, and that it is placed in the
51 * main party list correctly */
52 static partylist *
53 form_party (object *op, const char *params)
54 {
55 partylist *newparty;
56
57 newparty = (partylist *) malloc (sizeof (partylist));
58 newparty->partyname = strdup (params);
59 newparty->total_exp = 0;
60 newparty->kills = 0;
61 newparty->passwd[0] = '\0';
62 newparty->next = NULL;
63 newparty->partyleader = strdup (op->name);
64 new_draw_info_format (NDI_UNIQUE, 0, op, "You have formed party: %s", newparty->partyname);
65 op->contr->party = newparty;
66
67 return newparty;
68 }
69
70 void
71 remove_party (partylist *target_party)
72 {
73 partylist *tmpparty;
74 partylist *previousparty;
75 partylist *nextparty;
76 player *pl;
77
78 if (firstparty == NULL)
79 {
80 LOG (llevError, "remove_party(): I was asked to remove party %s, but no parties are defined", target_party->partyname);
81 return;
82 }
83
84 for_all_players (pl)
85 if (pl->party == target_party)
86 pl->party = NULL;
87
88 /* special case-ism for parties at the beginning and end of the list */
89 if (target_party == firstparty)
90 {
91 firstparty = firstparty->next;
92
93 if (target_party->partyleader)
94 free (target_party->partyleader);
95
96 if (target_party->partyname)
97 free (target_party->partyname);
98
99 free (target_party);
100 return;
101 }
102 else if (target_party == lastparty)
103 {
104 for (tmpparty = firstparty; tmpparty->next != NULL; tmpparty = tmpparty->next)
105 {
106 if (tmpparty->next == target_party)
107 {
108 lastparty = tmpparty;
109
110 if (target_party->partyleader)
111 free (target_party->partyleader);
112
113 if (target_party->partyname)
114 free (target_party->partyname);
115
116 free (target_party);
117 lastparty->next = NULL;
118 return;
119 }
120 }
121 }
122 for (tmpparty = firstparty; tmpparty->next != NULL; tmpparty = tmpparty->next)
123 if (tmpparty->next == target_party)
124 {
125 previousparty = tmpparty;
126 nextparty = tmpparty->next->next;
127 /* this should be safe, because we already dealt with the lastparty case */
128
129 previousparty->next = nextparty;
130 if (target_party->partyleader)
131 free (target_party->partyleader);
132 if (target_party->partyname)
133 free (target_party->partyname);
134 free (target_party);
135 return;
136 }
137 }
138
139 /* Remove unused parties, this could be made to scale a lot better. */
140 void
141 obsolete_parties (void)
142 {
143 int player_count;
144 player *pl;
145 partylist *party;
146 partylist *next = NULL;
147
148 if (!firstparty)
149 return; /* we can't obsolete parties if there aren't any */
150 for (party = firstparty; party != NULL; party = next)
151 {
152 next = party->next;
153 player_count = 0;
154 for_all_players (pl)
155 if (pl->party == party)
156 player_count++;
157 if (player_count == 0)
158 remove_party (party);
159 }
160 }
161
162 void
163 add_kill_to_party (partylist *party, char *killer, char *dead, long exp)
164 {
165 int i, pos;
166
167 if (party == NULL)
168 return;
169
170 if (party->kills >= PARTY_KILL_LOG)
171 {
172 pos = PARTY_KILL_LOG - 1;
173 for (i = 0; i < PARTY_KILL_LOG - 1; i++)
174 party->party_kills[i] = party->party_kills[i + 1];
175 }
176 else
177 pos = party->kills;
178
179 party->kills++;
180 party->total_exp += exp;
181 party->party_kills[pos].exp = exp;
182 assign (party->party_kills[pos].killer, killer);
183 assign (party->party_kills[pos].dead, dead);
184 party->party_kills[pos].killer[MAX_NAME] = 0;
185 party->party_kills[pos].dead[MAX_NAME] = 0;
186 }
187
188 int
189 confirm_party_password (object *op)
190 {
191 partylist *tmppartylist;
192
193 for (tmppartylist = firstparty; tmppartylist != NULL; tmppartylist = tmppartylist->next)
194 {
195 if (!strcmp (op->contr->party_to_join->partyname, tmppartylist->partyname))
196 {
197 if (strcmp (op->contr->write_buf + 1, tmppartylist->passwd) == 0)
198 return 0;
199 else
200 return 1;
201 }
202 }
203 return 1;
204 }
205
206 void
207 receive_party_password (object *op, char k)
208 {
209
210 if (confirm_party_password (op) == 0)
211 {
212 partylist *joined_party = op->contr->party_to_join;
213 char buf[MAX_BUF];
214
215 op->contr->party = op->contr->party_to_join;
216 op->contr->party_to_join = NULL;
217 new_draw_info_format (NDI_UNIQUE, 0, op, "You have joined party: %s\n", joined_party->partyname);
218 snprintf (buf, MAX_BUF, "%s joins party %s", &op->name, joined_party->partyname);
219 send_party_message (op, buf);
220 op->contr->ns->state = ST_PLAYING;
221 return;
222 }
223 else
224 {
225 new_draw_info (NDI_UNIQUE, 0, op, "You entered the wrong password");
226 op->contr->party_to_join = NULL;
227 op->contr->ns->state = ST_PLAYING;
228 return;
229 }
230 }
231
232 void
233 send_party_message (object *op, char *msg)
234 {
235 player *pl;
236
237 for_all_players (pl)
238 if (pl->ob->contr->party == op->contr->party && pl->ob != op)
239 new_draw_info (NDI_WHITE, 0, pl->ob, msg);
240 }
241
242 int
243 command_gsay (object *op, char *params)
244 {
245 char party_params[MAX_BUF];
246
247 if (!params)
248 return 0;
249
250 strcpy (party_params, "say ");
251 strcat (party_params, params);
252 command_party (op, party_params);
253 return 0;
254 }
255
256 int
257 command_party (object *op, char *params)
258 {
259 char buf[MAX_BUF];
260 partylist *tmpparty, *oldparty; /* For iterating over linked list */
261 char *currentparty; /* For iterating over linked list */
262
263 if (params == NULL)
264 {
265 if (op->contr->party == NULL)
266 {
267 new_draw_info (NDI_UNIQUE, 0, op, "You are not a member of any party.");
268 new_draw_info (NDI_UNIQUE, 0, op, "For help try: party help");
269 }
270 else
271 {
272 currentparty = op->contr->party->partyname;
273 new_draw_info_format (NDI_UNIQUE, 0, op, "You are a member of party %s.", currentparty);
274 }
275 return 1;
276 }
277
278 if (strcmp (params, "help") == 0)
279 {
280 new_draw_info (NDI_UNIQUE, 0, op, "To form a party type: party form <partyname>");
281 new_draw_info (NDI_UNIQUE, 0, op, "To join a party type: party join <partyname>");
282 new_draw_info (NDI_UNIQUE, 0, op, "If the party has a passwd, it will you prompt you for it.");
283 new_draw_info (NDI_UNIQUE, 0, op, "For a list of current parties type: party list");
284 new_draw_info (NDI_UNIQUE, 0, op, "To leave a party type: party leave");
285 new_draw_info (NDI_UNIQUE, 0, op, "To change a passwd for a party type: party passwd <password>");
286 new_draw_info (NDI_UNIQUE, 0, op, "There is an 8 character max");
287 new_draw_info (NDI_UNIQUE, 0, op, "To talk to party members type: party say <msg>");
288 new_draw_info (NDI_UNIQUE, 0, op, "To see who is in your party: party who");
289 new_draw_info (NDI_UNIQUE, 0, op, "To see what you've killed, type: party kills");
290 return 1;
291 }
292
293 if (!strncmp (params, "kills", 5))
294 {
295 int i, max;
296 char chr;
297 char buffer[80];
298 float exp;
299
300 if (op->contr->party == NULL)
301 {
302 new_draw_info (NDI_UNIQUE, 0, op, "You are not a member of any party.");
303 return 1;
304 }
305 tmpparty = op->contr->party;
306 if (!tmpparty->kills)
307 {
308 new_draw_info (NDI_UNIQUE, 0, op, "You haven't killed anything yet.");
309 return 1;
310 }
311 max = tmpparty->kills - 1;
312 if (max > PARTY_KILL_LOG - 1)
313 max = PARTY_KILL_LOG - 1;
314 new_draw_info (NDI_UNIQUE, 0, op, "Killed | Killer| Exp");
315 new_draw_info (NDI_UNIQUE, 0, op, "----------------+----------------+--------");
316 for (i = 0; i <= max; i++)
317 {
318 exp = tmpparty->party_kills[i].exp;
319 chr = ' ';
320 if (exp > 1000000)
321 {
322 exp /= 1000000;
323 chr = 'M';
324 }
325 else if (exp > 1000)
326 {
327 exp /= 1000;
328 chr = 'k';
329 }
330 sprintf (buffer, "%16s|%16s|%6.1f%c", tmpparty->party_kills[i].dead, tmpparty->party_kills[i].killer, exp, chr);
331 new_draw_info (NDI_UNIQUE, 0, op, buffer);
332 }
333 exp = tmpparty->total_exp;
334 chr = ' ';
335 if (exp > 1000000)
336 {
337 exp /= 1000000;
338 chr = 'M';
339 }
340 else if (exp > 1000)
341 {
342 exp /= 1000;
343 chr = 'k';
344 }
345 new_draw_info (NDI_UNIQUE, 0, op, "----------------+----------------+--------");
346 sprintf (buffer, "Totals: %d kills, %.1f%c exp", tmpparty->kills, exp, chr);
347 new_draw_info (NDI_UNIQUE, 0, op, buffer);
348 return 1;
349 }
350
351 if (strncmp (params, "say ", 4) == 0)
352 {
353 if (op->contr->party == NULL)
354 {
355 new_draw_info (NDI_UNIQUE, 0, op, "You are not a member of any party.");
356 return 1;
357 }
358 params += 4;
359 currentparty = op->contr->party->partyname;
360 snprintf (buf, MAX_BUF - 1, "[%s] %s says: %s", currentparty, &op->name, params);
361 send_party_message (op, buf);
362 new_draw_info_format (NDI_LT_GREEN | NDI_UNIQUE, 0, op, "[%s] You say: %s", currentparty, params);
363 return 1;
364 }
365
366 if (strncmp (params, "form ", 5) == 0)
367 {
368 int player_count;
369 player *pl;
370
371 params += 5;
372 if (op->contr->party)
373 oldparty = op->contr->party;
374 else
375 oldparty = NULL;
376
377 if (firstparty)
378 {
379 for (tmpparty = firstparty; tmpparty != NULL; tmpparty = tmpparty->next)
380 {
381 if (!strcmp (tmpparty->partyname, params))
382 {
383 new_draw_info_format (NDI_UNIQUE, 0, op, "The party %s already exists, pick another name", params);
384 return 1;
385 }
386 }
387 lastparty->next = form_party (op, params);
388 lastparty = lastparty->next;
389 }
390 else
391 {
392 firstparty = form_party (op, params);
393 lastparty = firstparty;
394 }
395 /*
396 * The player might have previously been a member of a party, if so, he will be leaving
397 * it, so check if there are any other members and if not, delete the party
398 */
399 player_count = 0;
400 if (oldparty)
401 {
402 for_all_players (pl)
403 if (pl->party == oldparty)
404 player_count++;
405
406 if (player_count == 0)
407 remove_party (oldparty);
408 }
409
410 return 0;
411 } /* form */
412
413 if (strcmp (params, "leave") == 0)
414 {
415 if (op->contr->party == NULL)
416 {
417 new_draw_info (NDI_UNIQUE, 0, op, "You are not a member of any party.");
418 return 1;
419 }
420 currentparty = op->contr->party->partyname;
421 new_draw_info_format (NDI_UNIQUE, 0, op, "You leave party %s.", currentparty);
422 sprintf (buf, "%s leaves party %s.", &op->name, currentparty);
423 send_party_message (op, buf);
424 op->contr->party = NULL;
425 return 1;
426 }
427
428 if (strcmp (params, "who") == 0)
429 {
430 player *pl;
431
432 tmpparty = op->contr->party;
433 if (op->contr->party == NULL)
434 {
435 new_draw_info (NDI_UNIQUE, 0, op, "You are not a member of any party.");
436 return 1;
437 }
438 new_draw_info_format (NDI_UNIQUE, 0, op, "Members of party: %s.", op->contr->party->partyname);
439 for_all_players (pl)
440 if (pl->ob->contr->party == op->contr->party)
441 {
442 if (settings.set_title == TRUE)
443 {
444 if (pl->ob->contr->own_title[0] != '\0')
445 sprintf (buf, "%3d %s the %s", pl->ob->level, &pl->ob->name, pl->ob->contr->own_title);
446 else
447 sprintf (buf, "%3d %s the %s", pl->ob->level, &pl->ob->name, pl->ob->contr->title);
448 }
449 else
450 sprintf (buf, "%3d %s the %s", pl->ob->level, &pl->ob->name, pl->ob->contr->title);
451 new_draw_info (NDI_UNIQUE, 0, op, buf);
452 }
453 return 1;
454 } /* leave */
455
456 if (strncmp (params, "passwd ", 7) == 0)
457 {
458 partylist *tmplist;
459
460 params += 7;
461
462 if (op->contr->party == NULL)
463 {
464 new_draw_info (NDI_UNIQUE, 0, op, "You are not a member of a party");
465 return 1;
466 }
467
468 if (strlen (params) > 8)
469 {
470 new_draw_info (NDI_UNIQUE, 0, op, "The password must not exceed 8 characters");
471 return 1;
472 }
473
474 tmplist = firstparty;
475 while (tmplist != NULL)
476 {
477 if (tmplist == op->contr->party)
478 {
479 strcpy (tmplist->passwd, params);
480 new_draw_info_format (NDI_UNIQUE, 0, op, "The password for party %s is %s", tmplist->partyname, tmplist->passwd);
481 snprintf (buf, MAX_BUF, "Password for party %s is now %s, changed by %s", tmplist->partyname, tmplist->passwd, &op->name);
482 send_party_message (op, buf);
483 return 0;
484 }
485 tmplist = tmplist->next;
486 }
487 return 0;
488 } /* passwd */
489
490 if (strcmp (params, "list") == 0)
491 {
492 partylist *tmplist;
493
494 tmplist = firstparty;
495
496 if (firstparty == NULL)
497 {
498 new_draw_info (NDI_UNIQUE, 0, op, "There are no parties active right now");
499 return 1;
500 }
501
502 new_draw_info (NDI_UNIQUE, 0, op, "Party name Leader");
503 new_draw_info (NDI_UNIQUE, 0, op, "---------- ------");
504
505 while (tmplist != NULL)
506 {
507 new_draw_info_format (NDI_UNIQUE, 0, op, "%-32s %s", tmplist->partyname, tmplist->partyleader);
508 tmplist = tmplist->next;
509 }
510 return 0;
511 } /* list */
512
513 if (strncmp (params, "join ", 5) == 0)
514 {
515
516 params += 5;
517
518 /* Can't join a party cause non exist */
519 if (firstparty == NULL)
520 {
521 new_draw_info_format (NDI_UNIQUE, 0, op, "Party: %s does not exist. You must form it first", params);
522 return 1;
523 }
524
525 /* Special case if thier is only one party */
526 if (firstparty->next == NULL)
527 {
528 if (strcmp (firstparty->partyname, params) != 0)
529 {
530 new_draw_info_format (NDI_UNIQUE, 0, op, "Party: %s does not exist. You must form it first", params);
531 return 1;
532 }
533 else
534 {
535 if (op->contr->party == firstparty)
536 {
537 new_draw_info_format (NDI_UNIQUE, 0, op, "You are already in party: %s", firstparty->partyname);
538 return 1;
539 }
540 /* found party player wants to join */
541 if (firstparty->passwd[0] == '\0')
542 {
543 op->contr->party = firstparty;
544 new_draw_info_format (NDI_UNIQUE, 0, op, "You have joined party: %s", firstparty->partyname);
545 snprintf (buf, MAX_BUF, "%s joins party %s", &op->name, firstparty->partyname);
546 send_party_message (op, buf);
547 return 0;
548 }
549 else
550 {
551 get_party_password (op, firstparty);
552 return 0;
553 }
554 }
555 }
556
557 tmpparty = firstparty;
558 while (tmpparty != NULL)
559 {
560 if (strcmp (tmpparty->partyname, params) == 0)
561 {
562 if (op->contr->party == tmpparty)
563 {
564 new_draw_info_format (NDI_UNIQUE, 0, op, "You are already a member of party: %s", tmpparty->partyname);
565 return 1;
566 }
567 else
568 {
569 if (tmpparty->passwd[0] == '\0')
570 {
571 new_draw_info_format (NDI_UNIQUE, 0, op, "You have joined party: %s", tmpparty->partyname);
572 op->contr->party = tmpparty;
573 snprintf (buf, MAX_BUF, "%s joins party %s", &op->name, tmpparty->partyname);
574 send_party_message (op, buf);
575 return 0;
576 }
577 else
578 {
579 get_party_password (op, tmpparty);
580 return 0;
581 }
582 }
583 }
584 else
585 tmpparty = tmpparty->next;
586 }
587
588 new_draw_info_format (NDI_UNIQUE, 0, op, "Party %s does not exist. You must form it first.", params);
589 return 1;
590 } /* join */
591
592 new_draw_info (NDI_UNIQUE, 0, op, "To form a party type: party form <partyname>");
593 new_draw_info (NDI_UNIQUE, 0, op, "To join a party type: party join <partyname>");
594 new_draw_info (NDI_UNIQUE, 0, op, "If the party has a passwd, it will you prompt you for it.");
595 new_draw_info (NDI_UNIQUE, 0, op, "For a list of current parties type: party list");
596 new_draw_info (NDI_UNIQUE, 0, op, "To leave a party type: party leave");
597 new_draw_info (NDI_UNIQUE, 0, op, "To change a passwd for a party type: party passwd <password>");
598 new_draw_info (NDI_UNIQUE, 0, op, "There is an 8 character max");
599 new_draw_info (NDI_UNIQUE, 0, op, "To talk to party members type: party say <msg>");
600 new_draw_info (NDI_UNIQUE, 0, op, "To see who is in your party: party who");
601 new_draw_info (NDI_UNIQUE, 0, op, "To see what you've killed, type: party kills");
602 return 1;
603 }