Crossfire Server, Trunk  R20513
party.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "sproto.h"
25 
26 static partylist *firstparty = NULL;
27 static partylist *lastparty = NULL;
40 partylist *party_form(object *op, const char *partyname) {
41  partylist *party;
42  char buf[MAX_BUF];
43 
44  snprintf(buf, sizeof(buf), "%s", partyname);
46 
47  if (party_find(buf) != NULL)
48  return NULL;
49 
50  party_leave(op);
51  party = (partylist *)malloc(sizeof(partylist));
52  party->partyname = strdup_local(buf);
53 #ifdef PARTY_KILL_LOG
54  party->total_exp = 0;
55  party->kills = 0;
56 #endif
57  party->passwd[0] = '\0';
58  party->next = NULL;
59  party->partyleader = strdup_local(op->name);
61  "You have formed party: %s",
62  party->partyname);
63  op->contr->party = party;
64 
65  if (lastparty) {
66  lastparty->next = party;
67  lastparty = lastparty->next;
68  } else {
69  firstparty = party;
70  lastparty = firstparty;
71  }
72 
73  return party;
74 }
75 
84 void party_join(object *op, partylist *party) {
85  char buf[MAX_BUF];
86 
87  party_leave(op);
88 
89  op->contr->party = party;
91  "You have joined party: %s\n",
92  party->partyname);
93  snprintf(buf, MAX_BUF, "%s joins party %s", op->name, party->partyname);
94  party_send_message(op, buf);
95 }
96 
104 void party_leave(object *op) {
105  char buf[MAX_BUF];
106 
107  if (op->contr->party == NULL) {
108  return;
109  }
110 
112  "You leave party %s.",
113  op->contr->party->partyname);
114  snprintf(buf, sizeof(buf), "%s leaves party %s.", op->name, op->contr->party->partyname);
115  party_send_message(op, buf);
116 
117  /*
118  * The player might have previously been a member of a party, if so, he will be leaving
119  * it, so check if there are any other members and if not, delete the party
120  */
121  if (op->contr->party != NULL) {
122  int party_found;
123  player *pl;
124 
125  party_found = 0;
126  for (pl = first_player; pl != NULL; pl = pl->next) {
127  if (pl != op->contr && pl->party == op->contr->party) {
128  party_found = 1;
129  break;
130  }
131  }
132  if (!party_found)
133  party_remove(op->contr->party);
134  }
135 
136  op->contr->party = NULL;
137 }
138 
147 partylist *party_find(const char *partyname) {
148  partylist *party;
149 
150  for (party = firstparty; party; party = party->next) {
151  if (strcmp(party->partyname, partyname) == 0)
152  return party;
153  }
154  return NULL;
155 }
156 
165 void party_remove(partylist *party) {
166  partylist *tmpparty;
167  partylist *previousparty;
168  partylist *nextparty;
169 
170  if (firstparty == NULL) {
171  LOG(llevError, "party_remove: I was asked to remove party %s, but no parties are defined\n",
172  party->partyname);
173  return;
174  }
175 
176  /* special case-ism for parties at the beginning and end of the list */
177  if (party == firstparty) {
178  if (lastparty == party)
179  lastparty = NULL;
180  firstparty = firstparty->next;
181  free(party->partyleader);
182  free(party->partyname);
183  free(party);
184  return;
185  } else if (party == lastparty) {
186  for (tmpparty = firstparty; tmpparty->next != NULL; tmpparty = tmpparty->next) {
187  if (tmpparty->next == party) {
188  lastparty = tmpparty;
189  free(party->partyleader);
190  free(party->partyname);
191  free(party);
192  lastparty->next = NULL;
193  return;
194  }
195  }
196  }
197  for (tmpparty = firstparty; tmpparty->next != NULL; tmpparty = tmpparty->next)
198  if (tmpparty->next == party) {
199  previousparty = tmpparty;
200  nextparty = tmpparty->next->next;
201  /* this should be safe, because we already dealt with the lastparty case */
202 
203  previousparty->next = nextparty;
204  free(party->partyleader);
205  free(party->partyname);
206  free(party);
207  return;
208  }
209 }
210 
218  return firstparty;
219 }
220 
230  return party->next;
231 }
232 
237  int player_count;
238  player *pl;
239  partylist *party;
240  partylist *next = NULL;
241 
242  if (!firstparty)
243  return; /* we can't obsolete parties if there aren't any */
244  for (party = firstparty; party != NULL; party = next) {
245  next = party->next;
246  player_count = 0;
247  for (pl = first_player; pl != NULL; pl = pl->next)
248  if (pl->party == party)
249  player_count++;
250  if (player_count == 0)
251  party_remove(party);
252  }
253 }
254 
263 const char *party_get_password(const partylist *party) {
264  return party->passwd;
265 }
266 
275 void party_set_password(partylist *party, const char *password) {
276  snprintf(party->passwd, sizeof(party->passwd), "%s", password);
278 }
279 
290 int party_confirm_password(const partylist *party, const char *password) {
291  return strcmp(party->passwd, password) == 0;
292 }
293 
305 void party_send_message(object *op, const char *message) {
306  player *pl;
307 
308  for (pl = first_player; pl != NULL; pl = pl->next)
309  if (pl->ob->contr->party == op->contr->party && pl->ob != op)
311  message);
312 }
313 
322 const char *party_get_leader(const partylist *party) {
323  return party->partyleader;
324 }
325 
326 #ifdef PARTY_KILL_LOG
327 
339 void party_add_kill(partylist *party, const char *killer, const char *dead, long exp) {
340  int i, pos;
341 
342  if (party->kills >= PARTY_KILL_LOG) {
343  pos = PARTY_KILL_LOG-1;
344  for (i = 0; i < PARTY_KILL_LOG-1; i++)
345  memcpy(&(party->party_kills[i]), &(party->party_kills[i+1]), sizeof(party->party_kills[0]));
346  } else
347  pos = party->kills;
348  party->kills++;
349  party->total_exp += exp;
350  party->party_kills[pos].exp = exp;
351  strncpy(party->party_kills[pos].killer, killer, MAX_NAME);
352  strncpy(party->party_kills[pos].dead, dead, MAX_NAME);
353  party->party_kills[pos].killer[MAX_NAME] = 0;
354  party->party_kills[pos].dead[MAX_NAME] = 0;
355 }
356 #endif
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Sends message to player(s).
Definition: main.c:315
Error, serious thing.
Definition: logger.h:11
partylist * party_get_first(void)
Returns the first party from the list of all parties.
Definition: party.c:217
One player.
Definition: player.h:92
const char * party_get_password(const partylist *party)
Returns the party&#39;s password.
Definition: party.c:263
const char * party_get_leader(const partylist *party)
Returns the name of the party&#39;s leader.
Definition: party.c:322
partylist * party_find(const char *partyname)
Find a party by name.
Definition: party.c:147
#define NDI_WHITE
Definition: newclient.h:222
#define strdup_local
Definition: compat.h:25
One party.
Definition: party.h:10
static partylist * firstparty
Keeps track of first party in list.
Definition: party.c:26
Global type definitions and header inclusions.
char * partyname
Party name.
Definition: party.h:14
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.c:310
partylist * party
Party this player is part of.
Definition: player.h:186
static partylist * lastparty
Keeps track of last party in list.
Definition: party.c:27
int party_confirm_password(const partylist *party, const char *password)
Checks whether a given password matches the party&#39;s password.
Definition: party.c:290
partylist * party_get_next(const partylist *party)
Returns the next party from the list of all parties.
Definition: party.c:229
void party_send_message(object *op, const char *message)
Send a message to all party members except the speaker.
Definition: party.c:305
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
Definition: newclient.h:379
#define MSG_TYPE_COMMAND_SUCCESS
Successful result from command.
Definition: newclient.h:510
struct party_struct * next
Next party in list.
Definition: party.h:13
#define snprintf
Definition: win32.h:46
const char * name
The name of the object, obviously...
Definition: object.h:311
void party_remove(partylist *party)
Removes and frees a party.
Definition: party.c:165
#define MSG_TYPE_COMMUNICATION
Communication between players.
Definition: newclient.h:386
void party_leave(object *op)
Makes a player leave his party.
Definition: party.c:104
void party_join(object *op, partylist *party)
Makes a player join a party.
Definition: party.c:84
struct pl * contr
Pointer to the player which control this object.
Definition: object.h:276
partylist * party_form(object *op, const char *partyname)
Forms the party struct for a party called &#39;partyname&#39;.
Definition: party.c:40
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
void replace_unprintable_chars(char *buf)
Replaces any unprintable character in the given buffer with a space.
Definition: utils.c:473
object * ob
The object representing the player.
Definition: player.h:158
void party_set_password(partylist *party, const char *password)
Sets a party&#39;s password.
Definition: party.c:275
char * partyleader
Who is the leader.
Definition: party.h:11
EXTERN player * first_player
First player.
Definition: global.h:117
struct pl * next
Pointer to next player, NULL if this is last.
Definition: player.h:93
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
void party_obsolete_parties(void)
Remove unused parties (no players), this could be made to scale a lot better.
Definition: party.c:236
#define MAX_NAME
Definition: define.h:41
char passwd[9]
Party password.
Definition: party.h:12
#define MSG_TYPE_COMMUNICATION_PARTY
Party message.
Definition: newclient.h:622