ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_party.C
Revision: 1.20
Committed: Sun Jul 1 05:00:19 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_2, rel-2_3
Changes since 1.19: +10 -11 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

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