ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_party.C
Revision: 1.4
Committed: Sat Sep 9 22:54:31 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +468 -396 lines
Log Message:
updated help and improved dependencies and makefiles

File Contents

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