ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_party.C
Revision: 1.42
Committed: Sat Nov 17 23:40:03 2018 UTC (5 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.41: +1 -0 lines
Log Message:
copyright update 2018

File Contents

# Content
1 /*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
6 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
7 * Copyright (©) 1992 Frank Tore Johansen
8 *
9 * Deliantra is free software: you can redistribute it and/or modify it under
10 * the terms of the Affero GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the Affero GNU General Public License
20 * and the GNU General Public License along with this program. If not, see
21 * <http://www.gnu.org/licenses/>.
22 *
23 * The authors can be reached via e-mail to <support@deliantra.net>
24 */
25
26 #include <global.h>
27 #include <sproto.h>
28 #include <spells.h>
29
30 static partylist *firstparty;
31
32 partylist *
33 get_firstparty ()
34 {
35 return firstparty;
36 }
37
38 static void
39 remove_party (partylist *target_party)
40 {
41 if (firstparty == NULL)
42 {
43 LOG (llevError, "remove_party(): I was asked to remove party %s, but no parties are defined", target_party->partyname);
44 return;
45 }
46
47 for_all_players (pl)
48 if (pl->party == target_party)
49 pl->party = NULL;
50
51 partylist **prevlink = &firstparty;
52
53 for (partylist *p = firstparty; p; p = p->next)
54 if (p->next == target_party)
55 {
56 prevlink = &p->next;
57 break;
58 }
59
60 *prevlink = target_party->next;
61
62 free (target_party->partyleader);
63 free (target_party->partyname);
64 sfree (target_party);
65 }
66
67 /* Remove unused parties, this could be made to scale a lot better. */
68 void
69 obsolete_parties ()
70 {
71 int player_count;
72 partylist *party;
73 partylist *next = NULL;
74
75 if (!firstparty)
76 return; /* we can't obsolete parties if there aren't any */
77
78 for (party = firstparty; party != NULL; party = next)
79 {
80 next = party->next;
81 player_count = 0;
82 for_all_players (pl)
83 if (pl->party == party)
84 player_count++;
85 if (player_count == 0)
86 remove_party (party);
87 }
88 }
89
90 void
91 add_kill_to_party (partylist *party, const char *killer, const char *dead, long exp)
92 {
93 int i, pos;
94
95 if (party == NULL)
96 return;
97
98 if (party->kills >= PARTY_KILL_LOG)
99 {
100 pos = PARTY_KILL_LOG - 1;
101 for (i = 0; i < PARTY_KILL_LOG - 1; i++)
102 party->party_kills[i] = party->party_kills[i + 1];
103 }
104 else
105 pos = party->kills;
106
107 party->kills++;
108 party->total_exp += exp;
109 party->party_kills[pos].exp = exp;
110 assign (party->party_kills[pos].killer, killer);
111 assign (party->party_kills[pos].dead, dead);
112 party->party_kills[pos].killer[MAX_NAME] = 0;
113 party->party_kills[pos].dead[MAX_NAME] = 0;
114 }
115
116 static int
117 confirm_party_password (object *op)
118 {
119 partylist *tmppartylist;
120
121 for (tmppartylist = firstparty; tmppartylist != NULL; tmppartylist = tmppartylist->next)
122 {
123 if (!strcmp (op->contr->party_to_join->partyname, tmppartylist->partyname))
124 {
125 if (strcmp (op->contr->write_buf + 1, tmppartylist->passwd) == 0)
126 return 0;
127 else
128 return 1;
129 }
130 }
131 return 1;
132 }
133
134 static void
135 send_party_message (object *op, const char *msg)
136 {
137 for_all_players (pl)
138 if (pl->ob->contr->party == op->contr->party && pl->ob != op)
139 pl->send_msg (NDI_UNIQUE, MSG_CHANNEL ("party"), msg);
140 }
141
142 void
143 receive_party_password (object *op, char k)
144 {
145
146 if (confirm_party_password (op) == 0)
147 {
148 partylist *joined_party = op->contr->party_to_join;
149 char buf[MAX_BUF];
150
151 op->contr->party = op->contr->party_to_join;
152 op->contr->party_to_join = NULL;
153 new_draw_info_format (NDI_UNIQUE, 0, op, "You have joined party: %s\n", joined_party->partyname);
154 snprintf (buf, MAX_BUF, "%s joins party %s", &op->name, joined_party->partyname);
155 send_party_message (op, buf);
156 op->contr->ns->state = ST_PLAYING;
157 return;
158 }
159 else
160 {
161 new_draw_info (NDI_UNIQUE, 0, op, "You entered the wrong password");
162 op->contr->party_to_join = NULL;
163 op->contr->ns->state = ST_PLAYING;
164 return;
165 }
166 }
167
168 int
169 command_gsay (object *op, char *params)
170 {
171 if (!params)
172 return 0;
173
174 command_party (op, format ("say %s", params));
175
176 return 0;
177 }
178
179 int
180 command_party (object *op, char *params)
181 {
182 dynbuf_text &buf = msg_dynbuf; buf.clear ();
183
184 partylist *party = op->contr->party;
185
186 if (!params)
187 params = (char *)"";
188
189 if (!strcmp (params, "help"))
190 buf << "\n"
191 " - To form a party type: C<party form> <partyname>\n"
192 " - To join a party type: C<party join> <partyname>\n"
193 " - If the party has a passwd, it will you prompt you for it.\n"
194 " - For a list of current parties type: C<party list>\n"
195 " - To leave a party type: C<party leave>\n"
196 " - To change a passwd for a party type: C<party passwd> <password>\n"
197 " - There is an 8 character max\n"
198 " - To talk to party members type: C<party say> <msg>\n"
199 " - To see who is in your party: C<party who>\n"
200 " - To see what you've killed, type: C<party kills>\n";
201 else if (strncmp (params, "form ", 5) == 0)
202 {
203 params += 5;
204
205 if (party)
206 buf << "You are already a member of party " << party->partyname << ". You must leave it first.";
207 else
208 {
209 for (partylist *tmpparty = firstparty; tmpparty; tmpparty = tmpparty->next)
210 {
211 if (!strcmp (tmpparty->partyname, params))
212 {
213 buf << "The party " << tmpparty->partyname << " already exists, pick another name";
214 goto reply;
215 }
216 }
217
218 /* Forms the party struct for a party called 'params'. it is the responsibility
219 * of the caller to ensure that the name is unique, and that it is placed in the
220 * main party list correctly */
221
222 party = salloc0<partylist> ();
223 party->partyname = strdup (params);
224 party->total_exp = 0;
225 party->kills = 0;
226 party->passwd[0] = '\0';
227 party->next = NULL;
228 party->partyleader = strdup (op->name);
229
230 buf << "You have formed party: " << party->partyname << ".";
231
232 party->next = firstparty;
233 op->contr->party = firstparty = party;
234 }
235 }
236 else if (strcmp (params, "list") == 0)
237 {
238 if (!firstparty)
239 buf << "There are no parties active right now";
240 else
241 {
242 buf << "Party name Leader\n\n"
243 "---------- ------\n\n";
244
245 for (partylist *p = firstparty; p; p = p->next)
246 buf.printf ("%-32s %s\n\n", p->partyname, p->partyleader);
247 }
248 }
249 else if (strncmp (params, "join ", 5) == 0)
250 {
251 params += 5;
252
253 /* Can't join a party cause non exist */
254 if (!firstparty)
255 buf << "Party: " << params << " does not exist. You must form it first.";
256 else if (party)
257 buf << "You are already a member of party " << party->partyname << ". You must leave it first.";
258 else
259 for (partylist *p = firstparty; p; p = p->next)
260 if (!strcmp (p->partyname, params))
261 {
262 if (!*p->passwd)
263 {
264 op->contr->party = p;
265
266 buf << op->name << " joins party " << p->partyname << ".";
267 send_party_message (op, buf);
268 buf.clear ();
269
270 buf << "You have joined party: " << p->partyname << ".";
271 }
272 else
273 get_party_password (op, p);
274
275 goto reply;
276 }
277 else
278 buf << "Party " << params << " does not exist. You must form it first.";
279 }
280 else if (!party)
281 buf << "You are not a member of any party.\n\n"
282 "For help try: C<party help>";
283 else if (!*params)
284 buf << "You are a member of party " << party->partyname << ".";
285 else if (!strncmp (params, "kills", 5))
286 {
287 if (!party->kills)
288 buf << "You haven't killed anything yet.";
289 else
290 {
291 int max = min (party->kills - 1, PARTY_KILL_LOG - 1);
292
293 buf << " Killed | Killer| Exp\n"
294 << " ----------------+----------------+--------\n";
295
296 for (int i = 0; i <= max; i++)
297 {
298 sint64 exp = party->party_kills[i].exp;
299 char suffix = ' ';
300 if (exp > 1000000)
301 {
302 exp /= 1000000;
303 suffix = 'M';
304 }
305 else if (exp > 1000)
306 {
307 exp /= 1000;
308 suffix = 'k';
309 }
310
311 buf.printf (" %16s|%16s|%6.1f%c\n", party->party_kills[i].dead, party->party_kills[i].killer, (double)exp, suffix);
312 }
313
314 buf << " ----------------+----------------+--------\n";
315
316 {
317 sint64 exp = party->total_exp;
318 char suffix = ' ';
319
320 if (exp > 1000000)
321 {
322 exp /= 1000000;
323 suffix = 'M';
324 }
325 else if (exp > 1000)
326 {
327 exp /= 1000;
328 suffix = 'k';
329 }
330
331 buf.printf (" Totals: %d kills, %.1f%c exp", party->kills, (double)exp, suffix);
332 }
333 }
334 }
335 else if (strncmp (params, "say ", 4) == 0)
336 {
337 params += 4;
338
339 buf << "[" << party->partyname << "] " << op->name << " says: " << params;
340 send_party_message (op, buf);
341 buf.clear ();
342
343 buf << "[" << party->partyname << "] You say: " << params;
344 }
345 else if (strcmp (params, "leave") == 0)
346 {
347 buf << op->name << " leaves party " << party->partyname << ".";
348 send_party_message (op, buf);
349 buf.clear ();
350
351 buf << "You leave party " << party->partyname << ".";
352
353 op->contr->party = 0;
354 obsolete_parties ();
355 }
356 else if (strcmp (params, "who") == 0)
357 {
358 buf << "Members of party " << party->partyname << ".\n";
359
360 for_all_players (pl)
361 if (pl->ob->contr->party == party)
362 buf.printf (" - %s/%d %s\n\n", &pl->ob->name, pl->ob->level,
363 *pl->ob->contr->own_title ? pl->ob->contr->own_title : pl->ob->contr->title);
364 }
365 else if (strncmp (params, "passwd ", 7) == 0)
366 {
367 params += 7;
368
369 if (strlen (params) > 8)
370 buf << "The password must not exceed 8 characters";
371 else
372 {
373 strcpy (party->passwd, params);
374 buf << "The password for party " << party->partyname << " is set to B<" << params << "> by " << &op->name;
375 }
376 }
377 else
378 buf << "I did not understand your command. For help try: C<party help>";
379
380 reply:
381 op->contr->send_msg (NDI_UNIQUE | NDI_REPLY, MSG_CHANNEL ("party"), buf);
382
383 return 1;
384 }