00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include <global.h>
00035 #ifndef __CEXTRACT__
00036 #include <sproto.h>
00037 #endif
00038 #include <spells.h>
00039
00040 static partylist *firstparty = NULL;
00041 static partylist *lastparty = NULL;
00048 partylist *get_firstparty(void) {
00049 return firstparty;
00050 }
00051
00052 void remove_party(partylist *target_party);
00053
00065 partylist *form_party(object *op, const char *params) {
00066 partylist *newparty;
00067
00068 if (op->contr->party != NULL) {
00069 char buf[MAX_BUF];
00070
00071 snprintf(buf, sizeof(buf), "%s leaves party %s.", op->name, op->contr->party->partyname);
00072 send_party_message(op, buf);
00073 }
00074 newparty = (partylist *)malloc(sizeof(partylist));
00075 newparty->partyname = strdup_local(params);
00076 replace_unprintable_chars(newparty->partyname);
00077 newparty->total_exp = 0;
00078 newparty->kills = 0;
00079 newparty->passwd[0] = '\0';
00080 newparty->next = NULL;
00081 newparty->partyleader = strdup_local(op->name);
00082 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00083 "You have formed party: %s",
00084 "You have formed party: %s",
00085 newparty->partyname);
00086 op->contr->party = newparty;
00087
00088 if (lastparty) {
00089 lastparty->next = newparty;
00090 lastparty = lastparty->next;
00091 } else {
00092 firstparty = newparty;
00093 lastparty = firstparty;
00094 }
00095
00096 return newparty;
00097 }
00098
00106 void remove_party(partylist *target_party) {
00107 partylist *tmpparty;
00108 partylist *previousparty;
00109 partylist *nextparty;
00110 player *pl;
00111
00112 if (firstparty == NULL) {
00113 LOG(llevError, "remove_party(): I was asked to remove party %s, but no parties are defined\n",
00114 target_party->partyname);
00115 return;
00116 }
00117 for (pl = first_player; pl != NULL; pl = pl->next)
00118 if (pl->party == target_party)
00119 pl->party = NULL;
00120
00121
00122 if (target_party == firstparty) {
00123 if (lastparty == target_party)
00124 lastparty = NULL;
00125 firstparty = firstparty->next;
00126 if (target_party->partyleader)
00127 free(target_party->partyleader);
00128 if (target_party->partyname)
00129 free(target_party->partyname);
00130 free(target_party);
00131 return;
00132 } else if (target_party == lastparty) {
00133 for (tmpparty = firstparty; tmpparty->next != NULL; tmpparty = tmpparty->next) {
00134 if (tmpparty->next == target_party) {
00135 lastparty = tmpparty;
00136 if (target_party->partyleader)
00137 free(target_party->partyleader);
00138 if (target_party->partyname)
00139 free(target_party->partyname);
00140 free(target_party);
00141 lastparty->next = NULL;
00142 return;
00143 }
00144 }
00145 }
00146 for (tmpparty = firstparty; tmpparty->next != NULL; tmpparty = tmpparty->next)
00147 if (tmpparty->next == target_party) {
00148 previousparty = tmpparty;
00149 nextparty = tmpparty->next->next;
00150
00151
00152 previousparty->next = nextparty;
00153 if (target_party->partyleader)
00154 free(target_party->partyleader);
00155 if (target_party->partyname)
00156 free(target_party->partyname);
00157 free(target_party);
00158 return;
00159 }
00160 }
00161
00165 void obsolete_parties(void) {
00166 int player_count;
00167 player *pl;
00168 partylist *party;
00169 partylist *next = NULL;
00170
00171 if (!firstparty)
00172 return;
00173 for (party = firstparty; party != NULL; party = next) {
00174 next = party->next;
00175 player_count = 0;
00176 for (pl = first_player; pl != NULL; pl = pl->next)
00177 if (pl->party == party)
00178 player_count++;
00179 if (player_count == 0)
00180 remove_party(party);
00181 }
00182 }
00183
00184 #ifdef PARTY_KILL_LOG
00185
00197 void add_kill_to_party(partylist *party, const char *killer, const char *dead, long exp) {
00198 int i, pos;
00199
00200 if (party == NULL)
00201 return;
00202 if (party->kills >= PARTY_KILL_LOG) {
00203 pos = PARTY_KILL_LOG-1;
00204 for (i = 0; i < PARTY_KILL_LOG-1; i++)
00205 memcpy(&(party->party_kills[i]), &(party->party_kills[i+1]), sizeof(party->party_kills[0]));
00206 } else
00207 pos = party->kills;
00208 party->kills++;
00209 party->total_exp += exp;
00210 party->party_kills[pos].exp = exp;
00211 strncpy(party->party_kills[pos].killer, killer, MAX_NAME);
00212 strncpy(party->party_kills[pos].dead, dead, MAX_NAME);
00213 party->party_kills[pos].killer[MAX_NAME] = 0;
00214 party->party_kills[pos].dead[MAX_NAME] = 0;
00215 }
00216 #endif
00217
00228 int confirm_party_password(object *op) {
00229 partylist *tmppartylist;
00230
00231 for (tmppartylist = firstparty; tmppartylist != NULL; tmppartylist = tmppartylist->next) {
00232 if (!strcmp(op->contr->party_to_join->partyname, tmppartylist->partyname)) {
00233 if (strcmp(op->contr->write_buf+1, tmppartylist->passwd) == 0)
00234 return 0;
00235 else
00236 return 1;
00237 }
00238 }
00239 return 1;
00240 }
00241
00248 void receive_party_password(object *op) {
00249
00250 if (confirm_party_password(op) == 0) {
00251 partylist *joined_party = op->contr->party_to_join;
00252 char buf[MAX_BUF];
00253
00254 if (op->contr->party != NULL) {
00255 snprintf(buf, sizeof(buf), "%s leaves party %s.", op->name, op->contr->party->partyname);
00256 send_party_message(op, buf);
00257 }
00258 op->contr->party = op->contr->party_to_join;
00259 op->contr->party_to_join = NULL;
00260 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00261 "You have joined party: %s\n",
00262 "You have joined party: %s\n",
00263 joined_party->partyname);
00264 snprintf(buf, MAX_BUF, "%s joins party %s", op->name, joined_party->partyname);
00265 send_party_message(op, buf);
00266 op->contr->state = ST_PLAYING;
00267 return;
00268 } else {
00269 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00270 "You entered the wrong password", NULL);
00271 op->contr->party_to_join = NULL;
00272 op->contr->state = ST_PLAYING;
00273 return;
00274 }
00275 }
00276
00285 void send_party_message(object *op, char *msg) {
00286 player *pl;
00287
00288 for (pl = first_player; pl != NULL; pl = pl->next)
00289 if (pl->ob->contr->party == op->contr->party && pl->ob != op)
00290 draw_ext_info(NDI_WHITE, 0, pl->ob, MSG_TYPE_COMMUNICATION, MSG_TYPE_COMMUNICATION_PARTY,
00291 msg, NULL);
00292 }
00293
00304 int command_gsay(object *op, char *params) {
00305 char party_params[MAX_BUF];
00306
00307 if (!params) {
00308 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR, "Say what?", NULL);
00309 return 0;
00310 }
00311 strcpy(party_params, "say ");
00312 strcat(party_params, params);
00313 command_party(op, party_params);
00314 return 0;
00315 }
00316
00323 static void party_help(object *op) {
00324 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_HELP,
00325 "To form a party type: party form <partyname>. "
00326 "To join a party type: party join <partyname> "
00327 "If the party has a passwd, it will you prompt you for it. "
00328 "For a list of current parties type: party list. "
00329 "To leave a party type: party leave "
00330 "To change a passwd for a party type: party passwd <password> "
00331 "There is an 8 character maximum password length. "
00332 "To talk to party members type: party say <msg> "
00333 "To see who is in your party: party who "
00334 #ifdef PARTY_KILL_LOG
00335 "To see what you've killed, type: party kills"
00336 #endif
00337 , NULL);
00338 }
00339
00350 int command_party(object *op, char *params) {
00351 char buf[MAX_BUF];
00352 partylist *tmpparty, *oldparty;
00353 char *currentparty;
00354
00355 if (params == NULL) {
00356 if (op->contr->party == NULL) {
00357 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00358 "You are not a member of any party. "
00359 "For help try: party help", NULL);
00360 } else {
00361 currentparty = op->contr->party->partyname;
00362 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00363 "You are a member of party %s.",
00364 "You are a member of party %s.",
00365 currentparty);
00366 }
00367 return 1;
00368 }
00369 if (strcmp(params, "help") == 0) {
00370 party_help(op);
00371 return 1;
00372 }
00373 #ifdef PARTY_KILL_LOG
00374 if (!strncmp(params, "kills", 5)) {
00375 int i, max;
00376 char chr;
00377 char buffer[80];
00378 float exp;
00379
00380 if (op->contr->party == NULL) {
00381 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00382 "You are not a member of any party.", NULL);
00383 return 1;
00384 }
00385 tmpparty = op->contr->party;
00386 if (!tmpparty->kills) {
00387 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00388 "You haven't killed anything yet.", NULL);
00389 return 1;
00390 }
00391 max = tmpparty->kills-1;
00392 if (max > PARTY_KILL_LOG-1)
00393 max = PARTY_KILL_LOG-1;
00394 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00395 "[fixed]Killed | Killer| Exp\n----------------+----------------+--------"
00396 "Killed | Killer| Exp\n----------------+----------------+--------",
00397 NULL);
00398
00399
00400 for (i = 0; i <= max; i++) {
00401 exp = tmpparty->party_kills[i].exp;
00402 chr = ' ';
00403 if (exp > 1000000) {
00404 exp /= 1000000;
00405 chr = 'M';
00406 } else if (exp > 1000) {
00407 exp /= 1000;
00408 chr = 'k';
00409 }
00410
00411 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00412 "[fixed]%16s|%16s|%6.1f%c",
00413 "%16s|%16s|%6.1f%c",
00414 tmpparty->party_kills[i].dead,
00415 tmpparty->party_kills[i].killer, exp, chr);
00416
00417 }
00418 exp = tmpparty->total_exp;
00419 chr = ' ';
00420 if (exp > 1000000) {
00421 exp /= 1000000;
00422 chr = 'M';
00423 } else if (exp > 1000) {
00424 exp /= 1000;
00425 chr = 'k';
00426 }
00427
00428 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00429 "[fixed]----------------+----------------+--------",
00430 "----------------+----------------+--------");
00431 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00432 "Totals: %d kills, %.1f%c exp", tmpparty->kills,
00433 "Totals: %d kills, %.1f%c exp", tmpparty->kills,
00434 exp, chr);
00435 return 1;
00436 }
00437 #endif
00438 if (strncmp(params, "say ", 4) == 0) {
00439 if (op->contr->party == NULL) {
00440 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00441 "You are not a member of any party.", NULL);
00442 return 1;
00443 }
00444 params += 4;
00445 currentparty = op->contr->party->partyname;
00446 snprintf(buf, MAX_BUF-1, "<%s> %s says: %s", currentparty, op->name, params);
00447 send_party_message(op, buf);
00448 draw_ext_info_format(NDI_WHITE, 0, op, MSG_TYPE_COMMUNICATION, MSG_TYPE_COMMUNICATION_PARTY,
00449 "<%s> You say: %s",
00450 "<%s> You say: %s",
00451 currentparty, params);
00452 return 1;
00453 }
00454
00455 if (strncmp(params, "form ", 5) == 0) {
00456 int player_count;
00457 player *pl;
00458
00459 params += 5;
00460 if (op->contr->party)
00461 oldparty = op->contr->party;
00462 else
00463 oldparty = NULL;
00464
00465 if (firstparty) {
00466 for (tmpparty = firstparty; tmpparty != NULL; tmpparty = tmpparty->next) {
00467 if (!strcmp(tmpparty->partyname, params)) {
00468 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00469 "The party %s already exists, pick another name",
00470 "The party %s already exists, pick another name",
00471 params);
00472 return 1;
00473 }
00474 }
00475 form_party(op, params);
00476 } else {
00477 form_party(op, params);
00478 }
00479
00480
00481
00482
00483 player_count = 0;
00484 if (oldparty) {
00485 for (pl = first_player; pl->next != NULL; pl = pl->next) {
00486 if (pl->party == oldparty)
00487 player_count++;
00488 }
00489 if (player_count == 0)
00490 remove_party(oldparty);
00491 }
00492 return 0;
00493 }
00494
00495 if (strcmp(params, "leave") == 0) {
00496 if (op->contr->party == NULL) {
00497 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00498 "You are not a member of any party.", NULL);
00499 return 1;
00500 }
00501 currentparty = op->contr->party->partyname;
00502 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00503 "You leave party %s.",
00504 "You leave party %s.",
00505 currentparty);
00506 snprintf(buf, sizeof(buf), "%s leaves party %s.", op->name, currentparty);
00507 send_party_message(op, buf);
00508 op->contr->party = NULL;
00509 return 1;
00510 }
00511 if (strcmp(params, "who") == 0) {
00512 if (op->contr->party == NULL) {
00513 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00514 "You are not a member of any party.", NULL);
00515 return 1;
00516 }
00517 list_players(op, NULL, op->contr->party);
00518 return 1;
00519 }
00520
00521 if (strncmp(params, "passwd ", 7) == 0) {
00522 partylist *tmplist;
00523
00524 params += 7;
00525
00526 if (op->contr->party == NULL) {
00527 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00528 "You are not a member of a party", NULL);
00529 return 1;
00530 }
00531
00532 if (strlen(params) > 8) {
00533 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00534 "The password must not exceed 8 characters", NULL);
00535 return 1;
00536 }
00537
00538 tmplist = firstparty;
00539 while (tmplist != NULL) {
00540 if (tmplist == op->contr->party) {
00541 strcpy(tmplist->passwd, params);
00542 replace_unprintable_chars(tmplist->passwd);
00543 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00544 "The password for party %s is %s",
00545 "The password for party %s is %s",
00546 tmplist->partyname, tmplist->passwd);
00547
00548 snprintf(buf, MAX_BUF, "Password for party %s is now %s, changed by %s",
00549 tmplist->partyname, tmplist->passwd, op->name);
00550 send_party_message(op, buf);
00551 return 0;
00552 }
00553 tmplist = tmplist->next;
00554 }
00555 return 0;
00556 }
00557
00558 if (strcmp(params, "list") == 0) {
00559 partylist *tmplist;
00560
00561 tmplist = firstparty;
00562
00563 if (firstparty == NULL) {
00564 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00565 "There are no parties active right now", NULL);
00566 return 1;
00567 }
00568
00569 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00570 "[fixed]Party name Leader\n---------- ------",
00571 "Party name Leader\n---------- ------");
00572
00573 while (tmplist != NULL) {
00574 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00575 "[fixed]%-32s %s",
00576 "%-32s %s",
00577 tmplist->partyname, tmplist->partyleader);
00578 tmplist = tmplist->next;
00579 }
00580 return 0;
00581 }
00582
00583 if (strncmp(params, "join ", 5) == 0) {
00584 params += 5;
00585
00586
00587 if (firstparty == NULL) {
00588 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00589 "Party: %s does not exist. You must form it first",
00590 "Party: %s does not exist. You must form it first",
00591 params);
00592 return 1;
00593 }
00594
00595
00596 if (firstparty->next == NULL) {
00597 if (strcmp(firstparty->partyname, params) != 0) {
00598 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00599 "Party: %s does not exist. You must form it first",
00600 "Party: %s does not exist. You must form it first",
00601 params);
00602 return 1;
00603 } else {
00604 if (op->contr->party == firstparty) {
00605 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00606 "You are already in party: %s",
00607 "You are already in party: %s",
00608 firstparty->partyname);
00609 return 1;
00610 }
00611
00612 if (firstparty->passwd[0] == '\0') {
00613 op->contr->party = firstparty;
00614 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00615 "You have joined party: %s",
00616 "You have joined party: %s",
00617 firstparty->partyname);
00618 snprintf(buf, MAX_BUF, "%s joins party %s", op->name, firstparty->partyname);
00619 send_party_message(op, buf);
00620 return 0;
00621 } else {
00622 get_party_password(op, firstparty);
00623 return 0;
00624 }
00625 }
00626 }
00627
00628 tmpparty = firstparty;
00629 while (tmpparty != NULL) {
00630 if (strcmp(tmpparty->partyname, params) == 0) {
00631 if (op->contr->party == tmpparty) {
00632 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00633 "You are already a member of party: %s",
00634 "You are already a member of party: %s",
00635 tmpparty->partyname);
00636 return 1;
00637 } else {
00638 if (tmpparty->passwd[0] == '\0') {
00639 if (op->contr->party != NULL) {
00640 snprintf(buf, sizeof(buf), "%s leaves party %s.", op->name, op->contr->party->partyname);
00641 send_party_message(op, buf);
00642 }
00643 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00644 "You have joined party: %s",
00645 "You have joined party: %s",
00646 tmpparty->partyname);
00647 op->contr->party = tmpparty;
00648 snprintf(buf, MAX_BUF, "%s joins party %s", op->name, tmpparty->partyname);
00649 send_party_message(op, buf);
00650 return 0;
00651 } else {
00652 get_party_password(op, tmpparty);
00653 return 0;
00654 }
00655 }
00656 } else
00657 tmpparty = tmpparty->next;
00658 }
00659
00660 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00661 "Party %s does not exist. You must form it first.",
00662 "Party %s does not exist. You must form it first.",
00663 params);
00664 return 1;
00665 }
00666
00667 party_help(op);
00668 return 1;
00669 }
00670
00672 static const char *rejoin_modes[] = {
00673 "no",
00674 "if_exists",
00675 "always",
00676 NULL
00677 };
00678
00688 int command_party_rejoin(object *op, char *params) {
00689 int mode;
00690
00691 if (!params) {
00692 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00693 "party rejoin: %s", NULL, rejoin_modes[op->contr->rejoin_party]);
00694 return 1;
00695 }
00696 for (mode = 0; rejoin_modes[mode] != NULL; mode++) {
00697 if (strcmp(rejoin_modes[mode], params) == 0) {
00698 op->contr->rejoin_party = mode;
00699 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00700 "party rejoin is now: %s", NULL, rejoin_modes[op->contr->rejoin_party]);
00701 return 1;
00702 }
00703 }
00704 if (strlen(params) > 50)
00705 params[50] = '\0';
00706 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00707 "invalid mode: %s", NULL, params);
00708 return 1;
00709 }