#include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "emlen.h" bool quit_flag = FALSE; void clear_tracks (CHAR_DATA * ch) { ROOM_DATA *rid; int hash; TRACK_DATA *tr; TRACK_DATA *tr_n; TRACK_DATA *tt; if (!ch) return; for (hash = 0; hash < HASH_MAX; hash++) { for (rid = room_hash[hash]; rid != NULL; rid = rid->next) { if (rid->tracks && rid->tracks->ch == ch) { tt = rid->tracks; rid->tracks = rid->tracks->next_track_in_room; free_m (tt); continue; } for (tr = rid->tracks; tr != NULL; tr = tr_n) { tr_n = tr->next_track_in_room; if (tr_n && tr_n->ch == ch) { tt = tr->next_track_in_room; tr->next_track_in_room = tr_n->next_track_in_room; free_m (tt); goto tt; } } tt: if (tr) {}; } } return; } void do_busy (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("busy", do_busy, POSITION_DEAD, 110, LOG_NORMAL, "Allows you to enter busy mode.") if (IS_MOB (ch)) return; if (LEVEL (ch) < 109) { send_to_char ("You may not go into busy mode unless you are a god.\n\r", ch); return; } if (ch->pcdata->quiet != 2) ch->pcdata->quiet = 2; else ch->pcdata->quiet = 0; if (ch->pcdata->quiet == 0) send_to_char ("You are no longer in busy mode! Prepare yourself!\n\r", ch); if (ch->pcdata->quiet == 2) send_to_char ("You have entered busy mode.\n\r", ch); return; } void do_action (CHAR_DATA * ch, char *argy) { int k; char *t; int empty = 0; int n1 = 0; int n2 = 0; char arg1[SML_LENGTH]; char arg2[SML_LENGTH]; char general_use[STD_LENGTH]; int an; DEFINE_COMMAND ("action", do_action, POSITION_DEAD, 0, LOG_NORMAL, "Allows you to set up actions, or delete/modify existing actions.") send_to_char ("Actions are disabled right now.\n\r", ch); return; SET_BIT (ch->special, ACTION_OFF); if (!ch || IS_MOB (ch)) { return; } for (k = 0; k < MAXALIAS; k++) if (!ch->pcdata->action[k] || ch->pcdata->action[k][0] == '\0' || !ch->pcdata->actionname[k] || ch->pcdata->actionname[k][0] == '\0') empty++; if (!argy || argy[0] == '\0') { if (empty == MAXALIAS) { send_to_char ("You have no actions. To set one up, use: Action \"<trigger>\" <action to perform>.\n\r", ch); return; } send_to_char ("\x1B[34;1m---------\x1B[35m[ Actions ]\x1B[34m---------\x1B[37;0m\n\r\n\r", ch); for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->action[k] && ch->pcdata->action[k][0] != '\0' && ch->pcdata->actionname[k] && ch->pcdata->actionname[k][0] != '\0') { char *iio; for (iio = ch->pcdata->action[k]; *iio != '\0'; iio++) { if (*iio == '~') *iio = '*'; } sprintf (general_use, "\x1B[1;30m[\x1B[34m%2d\x1B[30m]\x1B[34m --> \x1B[32m%-22s\x1B[34m Then Do: \x1B[37m\"%s\"\x1B[37;0m\n\r", k + 1, ch->pcdata->actionname[k], ch->pcdata->action[k]); send_to_char (general_use, ch); for (iio = ch->pcdata->action[k]; *iio != '\0'; iio++) { if (*iio == '*') *iio = '~'; } } } return; } argy = one_argy (argy, arg1); one_argy (argy, arg2); if (argy[0] == '{' && argy[strlen (argy) - 1] == '}') { argy[strlen (argy) - 1] = '\0'; argy++; } for (t = arg1; *t != '\0'; t++) { if (*t == '^') n1++; if (*t == '&') n2++; if (n1 > 1 || n2 > 1) { send_to_char ("You may not have more than ONE ^ or & in your action TRIGGER.\n\r", ch); return; } } if (!arg2 || arg2[0] == '\0') { for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->actionname[k] && !str_cmp (arg1, ch->pcdata->actionname[k])) { sprintf (general_use, "Deleted action #%d.\n\r", k + 1); send_to_char (general_use, ch); free_string (ch->pcdata->actionname[k]); free_string (ch->pcdata->action[k]); ch->pcdata->actionname[k] = NULL; ch->pcdata->action[k] = NULL; return; } } an = atoi (arg1); if (an > 0) { for (k = 0; k < MAXALIAS; k++) { if (an == (k + 1)) { if (!ch->pcdata->actionname[k]) { send_to_char ("That action number does not exist!\n\r", ch); return; } sprintf (general_use, "Deleted action #%d.\n\r", k + 1); send_to_char (general_use, ch); free_string (ch->pcdata->actionname[k]); free_string (ch->pcdata->action[k]); ch->pcdata->actionname[k] = NULL; ch->pcdata->action[k] = NULL; return; } } } sprintf (general_use, "Action \"%s\" not found.\n\r", arg1); send_to_char (general_use, ch); return; } if (empty == 0) { send_to_char ("You have no free action entries. You must delete one before adding\n\rany more.\n\r", ch); return; } if (strlen (arg1) < 5) { send_to_char ("Action triggers must be at least 5 letters long.\n\r", ch); return; } for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->actionname[k] && !str_cmp (arg1, ch->pcdata->actionname[k])) { char *msk; free_string (ch->pcdata->actionname[k]); free_string (ch->pcdata->actionname[k]); ch->pcdata->actionname[k] = str_dup (arg1); ch->pcdata->action[k] = str_dup (argy); for (msk = ch->pcdata->action[k]; *msk != '\0'; msk++) if (*msk == '*') *msk = '~'; break; } } if (k == MAXALIAS) for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->actionname[k] == '\0' || !ch->pcdata->actionname[k] || !ch->pcdata->action[k] || ch->pcdata->action[k] == '\0') { char *msk; ch->pcdata->actionname[k] = str_dup (arg1); ch->pcdata->action[k] = str_dup (argy); for (msk = ch->pcdata->action[k]; *msk != '\0'; msk++) if (*msk == '*') *msk = '~'; break; } } sprintf (general_use, "\x1B[34;1m[\x1B[37mAdded action #%d\x1B[34m]\x1B[37;0m\n\r", k + 1); send_to_char (general_use, ch); return; } void do_alias (CHAR_DATA * ch, char *argy) { int k; int empty = 0; char *t; char arg1[SML_LENGTH]; char arg2[SML_LENGTH]; char general_use[STD_LENGTH]; int an; DEFINE_COMMAND ("alias", do_alias, POSITION_DEAD, 0, LOG_NORMAL, "Allows you to set up an alias expansion, or delete/modify existing aliases.") if (!ch || IS_MOB (ch)) return; for (k = 0; k < MAXALIAS; k++) if (!ch->pcdata->alias[k] || ch->pcdata->alias[k][0] == '\0' || !ch->pcdata->aliasname[k] || ch->pcdata->aliasname[k][0] == '\0') empty++; if (!argy || argy[0] == '\0') { if (empty == MAXALIAS) { send_to_char ("You have no aliases. To set one up, use: Alias <name> <expansion>.\n\r", ch); return; } send_to_char ("\x1B[34;1m---------\x1B[35m[ Aliases ]\x1B[34m---------\x1B[37;0m\n\r\n\r", ch); for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->alias[k] && ch->pcdata->alias[k][0] != '\0' && ch->pcdata->aliasname[k] && ch->pcdata->aliasname[k][0] != '\0') { char *iio; for (t = ch->pcdata->alias[k]; *t != '\0'; t++) { if (*t == '%') *t = '@'; } for (t = ch->pcdata->aliasname[k]; *t != '\0'; t++) { if (*t == '%') *t = '@'; } for (iio = ch->pcdata->alias[k]; *iio != '\0'; iio++) { if (*iio == '~') *iio = '*'; } sprintf (general_use, "\x1B[1;30m[\x1B[34m%2d\x1B[30m]\x1B[34m --> \x1B[32m%-10s\x1B[34m Expansion: \x1B[37m\"%s\"\x1B[37;0m\n\r", k + 1, ch->pcdata->aliasname[k], ch->pcdata->alias[k]); send_to_char (general_use, ch); for (iio = ch->pcdata->alias[k]; *iio != '\0'; iio++) { if (*iio == '*') *iio = '~'; } } } return; } argy = one_argy (argy, arg1); one_argy (argy, arg2); if (argy[0] == '{' && argy[strlen (argy) - 1] == '}') { argy[strlen (argy) - 1] = '\0'; argy++; } if (!arg2 || arg2[0] == '\0') { for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->aliasname[k] && !str_cmp (arg1, ch->pcdata->aliasname[k])) { sprintf (general_use, "Deleted alias #%d.\n\r", k + 1); send_to_char (general_use, ch); free_string (ch->pcdata->aliasname[k]); free_string (ch->pcdata->alias[k]); ch->pcdata->aliasname[k] = NULL; ch->pcdata->alias[k] = NULL; return; } } an = atoi (arg1); if (an > 0) { for (k = 0; k < MAXALIAS; k++) { if (an == (k + 1)) { if (!ch->pcdata->aliasname[k]) { send_to_char ("That alias number does not exist!\n\r", ch); return; } sprintf (general_use, "Deleted alias #%d.\n\r", k + 1); send_to_char (general_use, ch); free_string (ch->pcdata->aliasname[k]); free_string (ch->pcdata->alias[k]); ch->pcdata->aliasname[k] = NULL; ch->pcdata->alias[k] = NULL; return; } } } sprintf (general_use, "Alias \"%s\" not found.\n\r", arg1); send_to_char (general_use, ch); return; } if (empty == 0) { send_to_char ("You have no free alias entries. You must delete one before adding\n\rany more.\n\r", ch); return; } if (strlen (arg1) == 1 && (arg1[0] == 'l' || arg1[0] == 'k' || arg1[0] == 'n' || arg1[0] == 's' || arg1[0] == 'e' || arg1[0] == 'w' || arg1[0] == 'i' || arg1[0] == 'u' || arg1[0] == 'd')) { send_to_char ("Aliases that begin with that letter must be more than 1 character long.\n\r", ch); return; } for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->aliasname[k] && !aliasok (ch->pcdata->aliasname[k], argy)) { send_to_char ("Recursive aliases are not acceptable!\n\r", ch); return; } } if (!aliasok (arg1, argy)) { send_to_char ("Partially recursive aliases are not acceptable!\n\r", ch); return; } for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->aliasname[k] && !str_cmp (arg1, ch->pcdata->aliasname[k])) { char *msk; free_string (ch->pcdata->alias[k]); free_string (ch->pcdata->aliasname[k]); ch->pcdata->aliasname[k] = str_dup (arg1); ch->pcdata->alias[k] = str_dup (argy); for (t = ch->pcdata->alias[k]; *t != '\0'; t++) { if (*t == '%') *t = '@'; } for (t = ch->pcdata->aliasname[k]; *t != '\0'; t++) { if (*t == '%') *t = '@'; } for (msk = ch->pcdata->alias[k]; *msk != '\0'; msk++) if (*msk == '*') *msk = '~'; break; } } if (k == MAXALIAS) for (k = 0; k < MAXALIAS; k++) { if (ch->pcdata->aliasname[k] == '\0' || !ch->pcdata->aliasname[k] || !ch->pcdata->alias[k] || ch->pcdata->alias[k] == '\0') { char *msk; ch->pcdata->aliasname[k] = str_dup (arg1); ch->pcdata->alias[k] = str_dup (argy); for (t = ch->pcdata->alias[k]; *t != '\0'; t++) { if (*t == '%') *t = '@'; } for (t = ch->pcdata->aliasname[k]; *t != '\0'; t++) { if (*t == '%') *t = '@'; } for (msk = ch->pcdata->alias[k]; *msk != '\0'; msk++) if (*msk == '*') *msk = '~'; break; } } sprintf (general_use, "\x1B[34;1m[\x1B[37mAdded alias #%d\x1B[34m]\x1B[37;0m\n\r", k + 1); send_to_char (general_use, ch); return; } void do_qui (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("qui", do_qui, POSITION_DEAD, 0, LOG_NORMAL, "This command is so you don't type q or qu and quit out by accident.") send_to_char ("Huh?\n\r", ch); return; } void do_quit (CHAR_DATA * ch, char *argy) { DESCRIPTOR_DATA *d; CHAR_DATA *bah_nir; CHAR_DATA *bah; char general_use[STD_LENGTH]; DEFINE_COMMAND ("quit", do_quit, POSITION_DEAD, 0, LOG_NORMAL, "This command saves your character and terminates the session.") if (IS_MOB (ch) && ch->desc != NULL) { do_return (ch, ""); return; } if (str_cmp(argy,"yyuu")) { if (ch->in_room && ch->in_room->sector_type == SECT_WATER_NOSWIM) { send_to_char ("You may not quit in an unswimmable water sector.\n\r", ch); return; } if (ch->in_room && ch->in_room->more && ch->in_room->more->linked_to) { send_to_char ("You cannot quit while in a vehicle.\n\r",ch); return; } if (ch->desc && !ch->desc->character) { ch->desc->character = ch; } if (IS_AFFECTED (ch, AFF_CHARM)) return; check_ced (ch); #ifndef NEW_WORLD if (ch->ced->in_boat != NULL) { send_to_char ("You cannot quit inside of a boat!!\n\r", ch); return; } #endif if (IN_BATTLE (ch)) { send_to_char ("You cannot quit in the battleground!\n\r", ch); return; } #ifdef NEW_WORLD if (LEVEL (ch) < 100) { ROOM_DATA *rrd; if (ch->in_room && ch->in_room->area && ch->in_room->area->can_quit == 2) { send_to_char ("You may not quit while in this zone.\n\r", ch); return; } if (!IS_EVIL (ch) && (rrd = get_room_index (1501)) != NULL && ch->in_room && ch->in_room->area != rrd->area && rrd->vnum > 1200 && ch->in_room->area->can_quit == 0 && IS_SET (ch->in_room->room_flags, ROOM_INDOORS)) { send_to_char ("You cannot quit while indoors. You may only quit in town or outside.\n\r", ch); return; } if (IS_EVIL (ch) && ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_INDOORS) && ch->in_room->area->can_quit == 0) { send_to_char ("You cannot quit while indoors.\n\r", ch); return; } } #endif if (ch->in_room && ch->in_room->vnum > 440 && ch->in_room->vnum < 700 && !ch->in_room->area->can_quit) { send_to_char ("You are not in a valid place in the world to quit.\n\r", ch); return; } if (CHALLENGE (ch) == 10) { send_to_char ("You must wait until after the arena battle!\n\r", ch); return; } if (auction_char == ch || e_auction_char == ch) { send_to_char ("Not while you are auctioning an item!\n\r", ch); return; } if (auction_tochar == ch || e_auction_tochar == ch) { send_to_char ("Not while you have the current bid on the auction!\n\r", ch); return; } if (ch->pcdata->no_quit_pk != 0) { sprintf (general_use, "Our records show you have recently been near or in combat with a player.\n\r"); send_to_char (general_use, ch); sprintf (general_use, "You must wait %d more game hours to quit.\n\r", ch->pcdata->no_quit_pk); send_to_char (general_use, ch); return; } if (ch->pcdata->no_quit != 0) { send_to_char ("Due to possibilities of avoiding hunting mobs and/or players, killing,\n\r", ch); send_to_char ("looting, then quitting out right away, you cannot quit from the game\n\r", ch); send_to_char ("this soon after combat. Combat with mobs sets the counter to 3 ticks,\n\r", ch); send_to_char ("combat with players sets the counter to 6 ticks, and encountering an\n\r", ch); send_to_char ("player opponent, sets the counter to 2 ticks.\n\r", ch); sprintf (general_use, "You must wait %d more game hours to quit.\n\r", ch->pcdata->no_quit); send_to_char (general_use, ch); return; } if (ch->position == POSITION_FIGHTING) { send_to_char ("You may not quit during combat.\n\r", ch); return; } if (ch->position < POSITION_STUNNED) { send_to_char ("You must wait until you die or recover to quit.\n\r", ch); return; } } /* End of quit for sure with yyuu */ /* Pray that they are not auctioning stuff.. or it might crashie! */ check_ced (ch); if (ch->ced->wasroom != 0) { char_from_room (ch); char_to_room (ch, get_room_index (ch->ced->wasroom)); } if (ch->in_room && ch->in_room->vnum > 500 && ch->in_room->vnum < 550) { fprintf (stderr, "Moved %s back into portal room from arena/waiting rooms.\n", NAME (ch)); char_from_room (ch); if (IS_EVIL (ch)) char_to_room (ch, get_room_index (99)); else char_to_room (ch, get_room_index (100)); } do_help (ch, "FAREWELL"); clear_tracks (ch); update_pbase (ch); if (IS_PLAYER (ch) && ch->pcdata->prompt != 0) { char tmps[500]; sprintf (tmps, "\x1B[1;%dr\x1B[2J", ch->pcdata->pagelen); write_to_descriptor2 (ch->desc, tmps, 0); } if (IS_PLAYER (ch) && ch->desc != NULL && IS_SET (ch->pcdata->act2, PLR_BLANKPROMPT)) { char tmps[500]; sprintf (tmps, "\x1B[1;%dr\x1B[2J", ch->pcdata->pagelen); write_to_descriptor2 (ch->desc, tmps, 0); } if (str_cmp (RNAME (ch), "Orin")) { sprintf (log_buf, "%s (%s@%s) has left the world.", NAME (ch), (ch->desc ? ch->desc->username : "nodesc"), (ch->desc ? ch->desc->host : "nodesc")); log_string (log_buf); sprintf (general_use, "Notify> %s has left the world.", NAME (ch)); do_global (general_use, LEVEL_IMMORTAL, WIZ_NOTIFY_LOGIN); if (LEVEL (ch) < LEVEL_IMMORTAL) act ("$n logged off.", ch, NULL, NULL, TO_NOTVICT); } /*for (bah=char_list;bah!=NULL;bah=bah->next) { if (IS_PLAYER(bah)) continue; if ( bah->npcdata->hire != NULL ) { if ( bah->npcdata->hire==ch || !get_player_world(bah, NAME(bah->npcdata->hire),FALSE) ) { bah->npcdata->hire = NULL; bah->npcdata->paid = 0; bah->leader = NULL; bah->master = NULL; continue; } } } */ NEW_POSITION(ch, POSITION_STANDING); ch->pcdata->number_pets = 0; sprintf (general_use, "%s logged off.\n\r", NAME (ch)); do_chan_notify (ch, general_use); if (LEVEL (ch) > 110) ch->pcdata->level = 1; save_char_obj (ch); save_char_tro (ch); if (ch->in_room) { for (bah = ch->in_room->more->people; bah != NULL; bah = bah_nir) { bah_nir = bah->next_in_room; if (IS_MOB (bah) && MASTER (bah) == ch && IS_AFFECTED (bah, AFF_CHARM)) { char_from_room (bah); check_fgt (bah); bah->fgt->master = NULL; extract_char (bah, TRUE); } } } d = ch->desc; quit_flag = TRUE; do_rawclear (ch, ""); extract_char (ch, TRUE); quit_flag = FALSE; if (d != NULL) { close_socket (d); } return; } void do_delete (CHAR_DATA * ch, char *argy) { DESCRIPTOR_DATA *d; PLAYERBASE_DATA *playerbase; char general_use[STD_LENGTH]; DEFINE_COMMAND ("delete", do_delete, POSITION_DEAD, 0, LOG_ALWAYS, "This command is used to delete your character permanently and irreversably.") if (FIGHTING (ch) != NULL || ch->position == POSITION_FIGHTING) return; check_ced (ch); #ifndef NEW_WORLD if (ch->ced->in_boat != NULL) { send_to_char ("You cannot delete inside of a boat!!\n\r", ch); return; } #endif if (ch->in_room && ch->in_room->vnum > 400 && ch->in_room->vnum < 700) { send_to_char ("You are not in a valid place in the world to delete.\n\r", ch); return; } if (IS_AFFECTED (ch, AFF_CHARM)) return; if (IN_BATTLE (ch)) { send_to_char ("You cannot delete in the battleground!\n\r", ch); return; } if (!str_cmp (argy, "character forever")) { if (CHALLENGE (ch) == 10) { send_to_char ("You must wait until after the arena battle!\n\r", ch); return; } if (auction_char == ch || e_auction_char == ch) { send_to_char ("Not while you are auctioning an item!\n\r", ch); return; } if (auction_tochar == ch || e_auction_tochar == ch) { send_to_char ("Not while you have the current bid on the auction!\n\r", ch); return; } clear_tracks (ch); save_char_obj (ch); sprintf (general_use, "%s%s.p", PLAYER_DIR_2, NAME (ch)); unlink (general_use); sprintf (general_use, "%s%s.cor", PLAYER_DIR_2, NAME (ch)); unlink (general_use); sprintf (general_use, "%s%s.tro", PLAYER_DIR_2, NAME (ch)); unlink (general_use); sprintf (general_use, "%s%s", PLAYER_DIR_2, NAME (ch)); unlink (general_use); for (playerbase = playerbase_zero; playerbase != NULL; playerbase = playerbase->next) { if (!str_cmp (playerbase->player_name, NAME (ch))) { playerbase->player_level = -1; save_playerbase (); break; } } sprintf (log_buf, "--> %s deleted self.", NAME (ch)); log_string (log_buf); sprintf (general_use, "Notify> %s has deleted self.", NAME (ch)); do_global (general_use, LEVEL_IMMORTAL, WIZ_NOTIFY_LOGIN); /*sprintf(general_use,"rm \"%s%s\" &",PLAYER_DIR_2,jumble_name(NAME(ch),FALSE)); system(general_use); */ d = ch->desc; extract_char (ch, TRUE); if (d != NULL) close_socket (d); return; } if (argy[0] == '\0') { send_to_char ("To delete this character permanently, type delete character forever\n\r", ch); return; } return; } void do_allsave (CHAR_DATA * ch, char *argy) { DESCRIPTOR_DATA *dd; DEFINE_COMMAND ("allsave", do_allsave, POSITION_DEAD, 110, LOG_ALWAYS, "This command forces a complete save of all characters.") for (dd = descriptor_list; dd != NULL; dd = dd->next) { if (!dd->character || dd->connected != CON_PLAYING) continue; write_to_descriptor2 (dd, "Forced save... saving your character.\n\r", 0); save_char_obj (dd->character); } return; } void do_save (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("save", do_save, POSITION_DEAD, 0, LOG_NORMAL, "This command is used to save your character.") if (IS_MOB (ch)) return; if (argy && argy != NULL && !str_cmp (argy, "xx2xx11")) { save_char_obj (ch); return; } send_to_char ("Saving... Successful.\n\r", ch); #ifdef NEW_WORLD if (number_range (1, 4) == 2) save_char_obj (ch); #endif return; } void do_follow (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; CHAR_DATA *victim; DEFINE_COMMAND ("follow", do_follow, POSITION_STANDING, 0, LOG_NORMAL, "This command allows you to follow a player or mob. See also Ditch and Group.") one_argy (argy, arg); if (arg[0] == '\0') { send_to_char ("Syntax: Follow <person>\n\r", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { send_to_char ("That person is either not here, or not visible to you.\n\r", ch); return; } if (LEVEL (victim) > 100 && LEVEL (ch) < 100) { send_to_char ("Mortals may not follow immorts!\n\r", ch); return; } if (IS_AFFECTED (ch, AFF_CHARM) && MASTER (ch) != NULL) { act ("You'd rather follow your master... $N!", ch, NULL, MASTER (ch), TO_CHAR); return; } if (victim == ch) { if (MASTER (ch) == NULL) { send_to_char ("Okay. You stop following anyone you were following.\n\r", ch); return; } stop_follower (ch); return; } conv_race (victim); conv_race (ch); if (not_is_same_align (ch, victim)) { if (IS_EVIL (victim)) { send_to_char ("FOLLOW AN ALIEN!? No way!\n\r", ch); } if (!IS_EVIL (victim)) { send_to_char ("FOLLOW THAT HUMANOID SCUM!? No way!\n\r", ch); } return; } if (MASTER (ch) != NULL) stop_follower (ch); add_follower (ch, victim); return; } void add_follower (CHAR_DATA * ch, CHAR_DATA * master) { if (MASTER (ch) != NULL) { bug ("Add_follower: non-null master.", 0); return; } check_fgt (ch); ch->fgt->master = master; ch->fgt->leader = NULL; if (can_see (master, ch)) act ("$n now follows you.", ch, NULL, master, TO_VICT); act ("You now follow $N.", ch, NULL, master, TO_CHAR); return; } void stop_follower (CHAR_DATA * ch) { char general_use[STD_LENGTH]; if (MASTER (ch) == NULL) { bug ("Stop_follower: null master.", 0); return; } if (IS_AFFECTED (ch, AFF_CHARM)) { REMOVE_BIT (ch->affected_by, AFF_CHARM); affect_strip (ch, gsn_charm_person); } if (can_see (MASTER (ch), ch)) act ("$n stops following you around.", ch, NULL, MASTER (ch), TO_VICT); act ("You stop following $N.", ch, NULL, MASTER (ch), TO_CHAR); if (LEADER (ch) != NULL) { sprintf (general_use, "%s has left the group.", NAME (ch)); group_notify (general_use, ch); } check_fgt (ch); ch->fgt->master = NULL; ch->fgt->leader = NULL; return; } void die_follower (CHAR_DATA * ch) { CHAR_DATA *fch; if (MASTER (ch) != NULL) stop_follower (ch); if (!ch->fgt) return; ch->fgt->leader = NULL; for (fch = char_list; fch != NULL; fch = fch->next) { if (MASTER (fch) == ch) stop_follower (fch); if (LEADER (fch) == ch) fch->fgt->leader = fch; } return; } int chars_in_group (CHAR_DATA * ch) { DESCRIPTOR_DATA *tch; int tally; tally = 0; if (IS_MOB (ch)) return 1; /*Just dummy value */ for (tch = descriptor_list; tch != NULL; tch = tch->next) { if (tch->character == NULL || tch->connected != CON_PLAYING) continue; if (is_same_group (ch, tch->character)) tally++; } if (tally == 0) tally = 1; return tally; } int rchars_in_group (CHAR_DATA * ch) { CHAR_DATA *tch; int tally; tally = 0; if (IS_MOB (ch)) return 1; /*Just dummy value */ for (tch = ch->in_room->more->people; tch != NULL; tch = tch->next_in_room) { if (IS_MOB (tch)) continue; if (is_same_group (ch, tch)) tally++; } if (tally == 0) tally = 1; return tally; } int tchars_in_group (CHAR_DATA * ch) { CHAR_DATA *tch; int tally; tally = 0; if (IS_MOB (ch)) return 1; /*Just dummy value */ for (tch = char_list; tch != NULL; tch = tch->next) { if (IS_MOB (tch)) continue; if (is_same_group (ch, tch)) tally++; } if (tally == 0) tally = 1; return tally; } void do_ditch (CHAR_DATA * ch, char *argy) { CHAR_DATA *ditchee; DEFINE_COMMAND ("ditch", do_ditch, POSITION_DEAD, 0, LOG_NORMAL, "This command allows you to ditch a following character.") if (argy == "" || argy[0] == '\0') { send_to_char ("Ditch whom?\n\r", ch); return; } if ((ditchee = get_char_world (ch, argy)) == NULL) { send_to_char ("Ditch Whom?\n\r", ch); return; } if (ditchee == ch) { send_to_char ("Ditch yourself? Get a clue...\n\r", ch); return; } if ((!MASTER (ditchee) || MASTER (ditchee) != ch) && (!LEADER (ditchee) || LEADER (ditchee) != ch)) { send_to_char ("Ditch Whom?\n\r", ch); return; } send_to_char ("Player successfully ditched.\n\r", ch); check_fgt (ditchee); ditchee->fgt->master = NULL; ditchee->fgt->leader = NULL; if (IS_AFFECTED (ditchee, AFF_CHARM)) REMOVE_BIT (ditchee->affected_by, AFF_CHARM); send_to_char ("The group leader has ditched you!\n\r", ditchee); return; } void do_group (CHAR_DATA * ch, char *argy) { char buf[STD_LENGTH]; char arg[SML_LENGTH]; int cig; CHAR_DATA *victim; int tcig; DEFINE_COMMAND ("group", do_group, POSITION_DEAD, 0, LOG_NORMAL, "This command allows you to group 'all' or playername. With no arguments, it shows info on your current group.") one_argy (argy, arg); if (arg[0] == '\0') { CHAR_DATA *gch; CHAR_DATA *leader; leader = (LEADER (ch) != NULL) ? LEADER (ch) : ch; sprintf (buf, "Group Leader [\x1B[37;1m%s\x1B[0m]\n\r\n\r", NAME (leader)); send_to_char (buf, ch); sprintf (buf, "%14s %-14s %-18s %-14s %s\n\r", "[-Char Power-]", "--Name--", "+-Health-+", "*-Stamina-*", "=-Exp2Lvl-="); send_to_char (buf, ch); for (gch = char_list; gch != NULL; gch = gch->next) { if (is_same_group (gch, ch)) { char tmp[40]; #ifndef NEW_WORLD if (gch == ch) sprintf(tmp, "%13d", LEVEL(ch)); else if (LEVEL (gch) < 4) strcpy (tmp, "Inexperienced"); else if (LEVEL (gch) < 12) strcpy (tmp, "Knowledgable"); else if (LEVEL (gch) < 27) strcpy (tmp, "Experienced"); else if (LEVEL (gch) < 45) strcpy (tmp, "Well-Known"); else if (LEVEL (gch) < 99) strcpy (tmp, "---Famous---"); else strcpy (tmp, "Immortal"); #endif #ifdef NEW_WORLD sprintf (buf, "[%s\x1B[30;1m%-6d\x1B[37;0m] \x1B[37;1m%-14s\x1B[0m \x1B[31;1m%-18s\x1B[34m %-14s\x1B[37;0m (%ld)\n\r", (IS_PLAYER(gch)?(NO_PKILL(gch)?"\x1B[33;1mNo-PK ":"\x1B[34;1mPKill "):""), LEVEL(gch), (IS_MOB (gch) ? gch->pIndexData->short_descr : capitalize (PERS (gch, ch))), STRING_HITS (gch), STRING_MOVES (gch), ((FIND_EXP (LEVEL (gch), gch->race)) - gch->exp)); send_to_char (buf, ch); #else sprintf (buf, "[\x1B[30;1m%13s\x1B[37;0m] \x1B[37;1m%-14s\x1B[0m \x1B[31;1m%-18s\x1B[34m %-14s\x1B[37;0m (%ld)\n\r", tmp, (IS_MOB (gch) ? gch->pIndexData->short_descr : capitalize (PERS (gch, ch))), STRING_HITS (gch), STRING_MOVES (gch), ((FIND_EXP (LEVEL (gch), gch->race)) - gch->exp)); send_to_char (buf, ch); #endif } } if (LEADER (ch) == NULL) cig = tchars_in_group (ch); else cig = tchars_in_group (LEADER (ch)); if (cig > 1) { sprintf (buf, "--Members in group: [\x1B[34;1m%d\x1B[37;0m]\n\r", cig); send_to_char (buf, ch); } return; } tcig = tchars_in_group (ch); /*added substitution, saves TONS of cpu */ if (!str_cmp (arg, "all")) { CHAR_DATA *gch; if (LEADER (ch) != NULL) { send_to_char ("You must be the leader of the group someone or ALL!\n\r", ch); return; } for (gch = char_list; gch != NULL; gch = gch->next) { if ( ch->in_room != NULL && !is_same_group (gch, ch) && ch->in_room == gch->in_room && MASTER (gch) != NULL && MASTER (gch) == ch && LEADER (gch) == NULL && tcig < 16) { check_fgt (gch); gch->fgt->leader = ch; act ("$N joins $n's group.", ch, NULL, gch, TO_NOTVICT); act ("You join $n's group.", ch, NULL, gch, TO_VICT); act ("$N joins your group.", ch, NULL, gch, TO_CHAR); sprintf (buf, "%s has joined the group!", NAME (gch)); group_notify (buf, ch); } } return; } /*end all */ if ((victim = get_player_world (ch, arg, FALSE)) == NULL || !can_see (ch, victim)) { send_to_char ("They aren't here.\n\r", ch); return; } if ((IS_EVIL (ch) && !IS_EVIL (victim)) || (!IS_EVIL (ch) && IS_EVIL (victim))) { send_to_char ("They aren't here.\n\r", ch); return; } if (MASTER (ch) != NULL || (LEADER (ch) != NULL && LEADER (ch) != ch)) { send_to_char ("You can follow two people at once!\n\r", ch); return; } if (MASTER (victim) != ch && ch != victim) { act ("$N must be following you in order to group up.", ch, NULL, victim, TO_CHAR); return; } if (ch == victim) { CHAR_DATA *tch; send_to_char ("You disband your group. All players stop following you.\n\r", ch); for (tch = char_list; tch != NULL; tch = tch->next) { if (is_same_group (tch, ch)) { check_fgt (tch); tch->fgt->leader = NULL; if (IS_PLAYER (tch)) tch->fgt->master = NULL; send_to_char ("The leader has disbanded the group, and you now follow no-one.\n\r", tch); } } return; } if (is_same_group (victim, ch)) { char buffy[200]; check_fgt (victim); victim->fgt->leader = NULL; sprintf (buffy, "%s removed %s from the group.", NAME (ch), NAME (victim)); group_notify (buffy, ch); return; } if (tcig > 14) { send_to_char ("Max limit of 15 players per group.\n\r", ch); return; } check_fgt (victim); victim->fgt->leader = ch; sprintf (buf, "%s has joined the group!", NAME (victim)); group_notify (buf, ch); return; } void do_split (CHAR_DATA * ch, char *argy) { char buf[STD_LENGTH]; char arg[STD_LENGTH]; CHAR_DATA *gch; char str1[1000]; char str2[1000]; int copper; int gold; int total_coinage; int members; int amount; int share; int counter; DEFINE_COMMAND ("split", do_split, POSITION_RESTING, 0, LOG_NORMAL, "This command can be used to split up coins. It will not make change.") if (!ch->in_room) return; argy = one_argy (argy, arg); if (arg[0] == '\0') { send_to_char ("Split how much?\n\r", ch); return; } amount = atoi (arg); if (!str_cmp (argy, "gold")) amount *= 100; if (amount < 0) { send_to_char ("Your group wouldn't like that.\n\r", ch); return; } if (amount == 0) { send_to_char ("Split nothing?\n\r", ch); return; } if (tally_coins (ch) < amount) { send_to_char ("You don't have that much money.\n\r", ch); return; } copper = 0; gold = 0; sprintf (str1, "%s", name_amount (amount)); if (amount >= 100) { gold = amount / 100; amount %= 100; } if (amount >= 1) { copper = amount; amount = 0; } while (ch->gold < gold) { ch->copper -= 100; ch->gold++; } while (ch->copper < amount) { ch->copper += 100; ch->gold--; } /*if (ch->gold<gold) { send_to_char("You don't have that many gold coins!\n\r",ch); return; } if (ch->copper<copper) { send_to_char("You don't have that many copper coins!\n\r",ch); return; } */ members = 0; ch->pcdata->voting_on = 0; for (gch = ch->in_room->more->people; gch != NULL; gch = gch->next_in_room) { if (is_same_group (gch, ch) && IS_PLAYER (gch)) { gch->pcdata->voting_on = 0; members++; } } if (members < 2) return; for (counter = 0; counter < 2; counter++) { if (counter == 0) amount = gold; if (counter == 1) amount = copper; if (amount < 1) continue; total_coinage = amount; share = 1; if (counter == 0) { amount *= 100; share *= 100; } sub_coins (amount, ch); while (total_coinage > 0) { create_amount (share, ch, NULL, NULL); /*Initial coin to the char */ ch->pcdata->voting_on += share; total_coinage--; if (total_coinage == 0) goto bah; for (gch = ch->in_room->more->people; gch != NULL; gch = gch->next_in_room) { if (IS_MOB (gch)) continue; if (gch != ch && is_same_group (gch, ch)) { total_coinage--; gch->pcdata->voting_on += share; create_amount (share, gch, NULL, NULL); if (total_coinage == 0) goto bah; } } } bah: if (share) {}; } /*End counter */ if (ch->pcdata->voting_on != 0) { sprintf (buf, "You split %s coins. You keep your share of %s coins.\n\r", str1, name_amount (ch->pcdata->voting_on)); ch->pcdata->voting_on = 0; send_to_char (buf, ch); } for (gch = ch->in_room->more->people; gch != NULL; gch = gch->next_in_room) { if (IS_MOB (gch)) continue; if (gch != ch && is_same_group (gch, ch)) { if (gch->pcdata->voting_on == 0) { sprintf (buf, "$n splits %s coins, but there is not enough to go around, and you receive nothing.", str1); act (buf, ch, NULL, gch, TO_VICT); continue; } sprintf (str2, "%s", name_amount (gch->pcdata->voting_on)); sprintf (buf, "$n splits %s coins. Your get your portion... %s coins.", str1, str2); gch->pcdata->voting_on = 0; act (buf, ch, NULL, gch, TO_VICT); } } return; } bool is_same_group (CHAR_DATA * ach, CHAR_DATA * bch) { if (LEADER (ach) != NULL) ach = LEADER (ach); if (LEADER (bch) != NULL) bch = LEADER (bch); return ach == bch; }