/* * $Id: act_comm.c 1019 2007-02-15 00:52:41Z zsuzsu $ */ /*************************************************************************** * ANATOLIA 2.1 is copyright 1996-1997 Serdar BULUT, Ibrahim CANPUNAR * * ANATOLIA has been brought to you by ANATOLIA consortium * * Serdar BULUT {Chronos} bulut@rorqual.cc.metu.edu.tr * * Ibrahim Canpunar {Asena} canpunar@rorqual.cc.metu.edu.tr * * Murat BICER {KIO} mbicer@rorqual.cc.metu.edu.tr * * D.Baris ACAR {Powerman} dbacar@rorqual.cc.metu.edu.tr * * By using this code, you have agreed to follow the terms of the * * ANATOLIA license, in the file Anatolia/anatolia.licence * ***************************************************************************/ /*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * **************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1995 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ #include <stdio.h> #include <sys/types.h> #include <sys/time.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> #include <time.h> #if !defined (WIN32) #include <unistd.h> #endif #include "merc.h" #include "debug.h" #include "fight.h" #include "quest.h" #include "mob_prog.h" #include "obj_prog.h" #include "auction.h" #include "db/lang.h" #include "db/gsn.h" #include "channels.h" /* command procedures needed */ DECLARE_DO_FUN(do_replay); DECLARE_DO_FUN(do_look); void do_afk(CHAR_DATA * ch, const char *argument) { if (!IS_IMMORTAL(ch) && !IS_SET(ch->comm, COMM_AFK)) { if (ch->in_room != NULL && !IS_SET(ch->in_room->room_flags, ROOM_SAFE)) char_puts ("Going {cAFK{x does not prevent you from being" " {RPK{xed, in fact some people take it as an" " opportunity to get an easy kill. It would be much" " wiser if you found a safe room first.\n", ch); else char_puts ("Ah, going {cAFK{x in a safe room, very wise!\n", ch); } if (IS_SET(ch->comm, COMM_AFK)) do_replay(ch, str_empty); else char_puts("You are now in {cAFK{x mode.\n", ch); TOGGLE_BIT(ch->comm, COMM_AFK); } /* RT code to delete yourself */ void do_delet(CHAR_DATA * ch, const char *argument) { char_puts("You must type the full command to delete yourself.\n", ch); } void do_delete(CHAR_DATA * ch, const char *argument) { if (IS_NPC(ch)) return; if (IS_SET(ch->acct_flags, ACCT_DELETING)) { if (argument[0] != '\0') { char_puts("Delete status removed.\n", ch); REMOVE_BIT(ch->acct_flags, ACCT_DELETING); return; } wiznet("$N turns $Mself into line noise.", ch, NULL, 0, 0, 0); delete_player(ch, NULL); return; } if (argument[0] != '\0') { char_puts("Just type delete. No argument.\n", ch); return; } char_puts("Type delete again to confirm this command.\n" "WARNING: this command is irreversible.\n" "Typing delete with an argument will undo delete status.\n", ch); SET_BIT(ch->acct_flags, ACCT_DELETING); wiznet("$N is contemplating deletion.", ch, NULL, 0, 0, ch->level); } void do_deaf(CHAR_DATA * ch, const char *argument) { if (IS_SET(ch->comm, COMM_DEAF)) { char_puts("You can now hear tells again.\n", ch); REMOVE_BIT(ch->comm, COMM_DEAF); } else { char_puts("From now on, you won't hear tells.\n", ch); SET_BIT(ch->comm, COMM_DEAF); } } /* RT quiet blocks out all communication */ void do_quiet(CHAR_DATA * ch, const char *argument) { if (IS_SET(ch->comm, COMM_QUIET)) { char_puts("Quiet mode removed.\n", ch); REMOVE_BIT(ch->comm, COMM_QUIET); } else { char_puts("From now on, you will only hear says and emotes.\n", ch); SET_BIT(ch->comm, COMM_QUIET); } } void do_replay(CHAR_DATA * ch, const char *argument) { if (IS_NPC(ch)) { char_puts("You can't replay.\n", ch); return; } page_to_char(buf_string(ch->pcdata->buffer), ch); buf_clear(ch->pcdata->buffer); } void do_whisper(CHAR_DATA * ch, const char *argument) { OBJ_DATA *char_obj; OBJ_DATA *char_obj_next; if (ch->position == POS_SLEEPING) { char_puts("In your dreams, or what?\n", ch); return; } if (argument[0] == '\0') { char_puts("Whisper what?\n", ch); return; } argument = garble(ch, argument); act_puts("You whisper '{r$t{x'", ch, argument, NULL, TO_CHAR | ACT_NODEAF, POS_DEAD); act("$n whispers '{r$t{x'", ch, argument, NULL, TO_ROOM | ACT_TOBUF | ACT_NOTWIT | ACT_STRANS | ACT_NODEAF | (IS_NPC(ch) && !IS_AFFECTED(ch, AFF_CHARM) ? ACT_TRANS : 0)); if (!IS_NPC(ch)) { CHAR_DATA *mob, *mob_next; for (mob = ch->in_room->people; mob != NULL; mob = mob_next) { mob_next = mob->next_in_room; if (IS_NPC(mob) && HAS_TRIGGER(mob, TRIG_SPEECH) && mob->position == mob->pIndexData->default_pos) mp_act_trigger(argument, mob, ch, NULL, NULL, TRIG_SPEECH); } } for (char_obj = ch->carrying; char_obj != NULL; char_obj = char_obj_next) { char_obj_next = char_obj->next_content; oprog_call(OPROG_SPEECH, char_obj, ch, argument); } for (char_obj = ch->in_room->contents; char_obj != NULL; char_obj = char_obj_next) { char_obj_next = char_obj->next_content; oprog_call(OPROG_SPEECH, char_obj, ch, argument); } } void do_say(CHAR_DATA * ch, const char *argument) { OBJ_DATA *char_obj; OBJ_DATA *char_obj_next; if (IS_NPC(ch) && IS_SET(ch->pIndexData->act, ACT_MUTE)) return; if (argument[0] == '\0') { char_puts("Say what?\n", ch); return; } argument = garble(ch, argument); act_puts("You say '{G$t{x'", ch, argument, NULL, TO_CHAR | ACT_NODEAF, POS_DEAD); act("$n says '{G$t{x'", ch, argument, NULL, TO_ROOM | ACT_TOBUF | ACT_NOTWIT | ACT_STRANS | ACT_NODEAF | (IS_NPC(ch) && !IS_AFFECTED(ch, AFF_CHARM) ? ACT_TRANS : 0)); if (!IS_NPC(ch)) { CHAR_DATA *mob, *mob_next; for (mob = ch->in_room->people; mob != NULL; mob = mob_next) { mob_next = mob->next_in_room; if (IS_NPC(mob) && HAS_TRIGGER(mob, TRIG_SPEECH) && mob->position == mob->pIndexData->default_pos) mp_act_trigger(argument, mob, ch, NULL, NULL, TRIG_SPEECH); } } for (char_obj = ch->carrying; char_obj != NULL; char_obj = char_obj_next) { char_obj_next = char_obj->next_content; oprog_call(OPROG_SPEECH, char_obj, ch, argument); } for (char_obj = ch->in_room->contents; char_obj != NULL; char_obj = char_obj_next) { char_obj_next = char_obj->next_content; oprog_call(OPROG_SPEECH, char_obj, ch, argument); } } /* this goes into act_comm.c */ void do_tell_raw(CHAR_DATA * ch, CHAR_DATA * victim, const char *msg) { char buf[MAX_STRING_LENGTH]; if (ch == victim) { char_puts("Talking to yourself, eh?\n", ch); return; } if (IS_AFFECTED(ch, AFF_SLEEP) && victim != ch->replyimm) { char_puts("In your dreams, or what?\n", ch); return; } if (IS_SET(ch->restricted_channels, CHAN_GLOBAL_TELL)) { char_puts("Your message didn't get through.\n", ch); return; } if ((victim == NULL) || (IS_NPC(victim) && victim->in_room != ch->in_room)) { char_puts("They aren't here.\n", ch); return; } if ((victim != ch->reply) && is_affected(victim, gsn_vampire) && !(IS_NPC(ch)) && !IS_IMMORTAL(ch)) { char_puts("They aren't here.\n", ch); return; } if (IS_SET(victim->comm, (COMM_QUIET | COMM_DEAF)) && !IS_IMMORTAL(ch) && !IS_IMMORTAL(victim)) { act_puts("$E is not receiving tells.", ch, 0, victim, TO_CHAR, POS_DEAD); return; } if (!IS_IMMORTAL(victim)) msg = garble(ch, msg); /* anonymous color for tells * so morts can keep track of how many wizi immorts * are talking */ if (IS_IMMORTAL(ch) && !can_see(victim, ch)) snprintf(buf, sizeof(buf), "{%cYou{x tell $N '{G$t{x'", ch->pcdata->anon_color ? ch->pcdata->anon_color : 'x'); else snprintf(buf, sizeof(buf), "You tell $N '{G$t{x'"); act_puts(buf, ch, msg, victim, TO_CHAR | ACT_NODEAF, POS_DEAD); if (IS_IMMORTAL(ch) && !can_see(victim, ch)) snprintf(buf, sizeof(buf), "{%c$n{x tells you '{G$t{x'", ch->pcdata->anon_color ? ch->pcdata->anon_color : 'x'); else snprintf(buf, sizeof(buf), "$n tells you '{G$t{x'"); act_puts(buf, ch, msg, victim, TO_VICT | ACT_TOBUF | ACT_NOTWIT | ACT_NODEAF | (IS_NPC(ch) && !IS_AFFECTED(ch, AFF_CHARM) ? ACT_TRANS : 0), POS_SLEEPING); if (IS_NPC(ch)) return; if (IS_NPC(victim)) { if (HAS_TRIGGER(victim, TRIG_SPEECH)) mp_act_trigger(msg, victim, ch, NULL, NULL, TRIG_SPEECH); } else { if (!IS_IMMORTAL(victim) && !IS_IMMORTAL(ch) && is_name(ch->name, victim->pcdata->twitlist)) return; if (victim->desc == NULL) act_puts("$N seems to have misplaced $S link but " "your tell will go through if $E returns.", ch, NULL, victim, TO_CHAR, POS_DEAD); else if (IS_SET(victim->comm, COMM_AFK)) act_puts("$E is AFK, but your tell will go through " "when $E returns.", ch, NULL, victim, TO_CHAR, POS_DEAD); victim->reply = ch; if (IS_IMMORTAL(ch)) victim->replyimm = ch; } } void do_tell(CHAR_DATA * ch, const char *argument) { char arg[MAX_INPUT_LENGTH]; argument = one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0' || argument[0] == '\0') { char_puts("Tell whom what?\n", ch); return; } do_tell_raw(ch, get_char_world(ch, arg), argument); } void do_reply(CHAR_DATA * ch, const char *argument) { do_tell_raw(ch, ch->reply, argument); } void do_replyimm(CHAR_DATA * ch, const char *argument) { do_tell_raw(ch, ch->replyimm, argument); } void do_noreply(CHAR_DATA * ch, const char *argument) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim = NULL; argument = one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0' || arg[0] == '\0') { char_puts("Refuse replies from whom?\n", ch); return; } if (!str_cmp(arg, "all")) { for (victim = char_list; victim && !IS_NPC(victim); victim = victim->next) if (victim != ch && !IS_IMMORTAL(victim)) { if (victim->reply == ch) victim->reply = NULL; if (victim->replyimm == ch) victim->replyimm = NULL; } } else { victim = get_char_world(ch, arg); if (victim != NULL && !IS_IMMORTAL(victim)) { if (victim != NULL && victim->reply == ch) victim->reply = NULL; if (victim != NULL && victim->replyimm == ch) victim->replyimm = NULL; } } char_puts("They will no longer reply to you.\n", ch); } void do_gtell(CHAR_DATA * ch, const char *argument) { CHAR_DATA *gch; int i; int flags; if (IS_AFFECTED(ch, AFF_SLEEP)) { char_puts("In your dreams, or what?\n", ch); return; } if (argument[0] == '\0') { char_puts("Tell your group what?\n", ch); return; } if (IS_SET(ch->restricted_channels, CHAN_GLOBAL_TELL)) { char_puts("Your message didn't get through!\n", ch); return; } argument = garble(ch, argument); flags = TO_VICT | ACT_TOBUF | ACT_STRANS | (IS_NPC(ch) && !IS_AFFECTED(ch, AFF_CHARM) ? ACT_TRANS : 0); for (i = 0, gch = char_list; gch; gch = gch->next) { if (IS_NPC(gch)) break; i++; if (is_same_group(gch, ch) && !is_affected(gch, gsn_deafen)) act_puts("$n tells the group '{G$t{x'", ch, argument, gch, flags, POS_DEAD); } if (i > 1 && !is_affected(ch, gsn_deafen)) act_puts("You tell your group '{G$t{x'", ch, argument, NULL, TO_CHAR, POS_DEAD); else char_puts("Quit talking to yourself. You are all alone.\n", ch); } void do_emote(CHAR_DATA * ch, const char *argument) { if (!IS_NPC(ch) && IS_SET(ch->restricted_channels, CHAN_GLOBAL_EMOTE)) { char_puts("You can't show your emotions.\n", ch); return; } if (argument[0] == '\0') { char_puts("Emote what?\n", ch); return; } argument = garble(ch, argument); act("$n $T", ch, NULL, argument, TO_ROOM | ACT_TOBUF | ACT_NOTRIG | ACT_NOTWIT | (IS_NPC(ch) && !IS_AFFECTED(ch, AFF_CHARM) ? ACT_TRANS : 0)); act("$n $T", ch, NULL, argument, TO_CHAR | ACT_NOTRIG); } void do_pmote(CHAR_DATA * ch, const char *argument) { CHAR_DATA *vch; const char *letter, *name; char last[MAX_INPUT_LENGTH], temp[MAX_STRING_LENGTH]; int matches = 0; int flags; if (!IS_NPC(ch) && IS_SET(ch->restricted_channels, CHAN_GLOBAL_EMOTE)) { char_puts("You can't show your emotions.\n", ch); return; } if (argument[0] == '\0') { char_puts("Emote what?\n", ch); return; } argument = garble(ch, argument); act("$n $t", ch, argument, NULL, TO_CHAR); flags = TO_CHAR | ACT_TOBUF | ACT_NOTWIT | ACT_NOTRIG | (IS_NPC(ch) && !IS_AFFECTED(ch, AFF_CHARM) ? ACT_TRANS : 0); for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room) { if (vch->desc == NULL || vch == ch) continue; if ((letter = strstr(argument, vch->name)) == NULL) { act("$N $t", vch, argument, ch, flags); continue; } strnzcpy(temp, sizeof(temp), argument); temp[strlen(argument) - strlen(letter)] = '\0'; last[0] = '\0'; name = vch->name; for (; *letter != '\0'; letter++) { if (*letter == '\'' && matches == strlen(vch->name)) { strnzcat(temp, sizeof(temp), "r"); continue; } if (*letter == 's' && matches == strlen(vch->name)) { matches = 0; continue; } if (matches == strlen(vch->name)) matches = 0; if (*letter == *name) { matches++; name++; if (matches == strlen(vch->name)) { strnzcat(temp, sizeof(temp), "you"); last[0] = '\0'; name = vch->name; continue; } strnzncat(last, sizeof(last), letter, 1); continue; } matches = 0; strnzcat(temp, sizeof(temp), last); strnzncat(temp, sizeof(temp), letter, 1); last[0] = '\0'; name = vch->name; } act("$N $t", vch, temp, ch, flags); } } void do_dmtalk(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_DM_WIZ); } void do_immtalk(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_WIZ); } void do_wizhelp(CHAR_DATA * ch, const char *argument) { if (argument[0] == '\0') { act_puts("Y{Gou must describe the problem you" " wish the immortal staff to address.{x", ch, argument, NULL, TO_CHAR, POS_DEAD); return; } if (IS_IMMORTAL(ch)) { char_puts("This channel is reserved for mortals" " asking for help.\n", ch); return; } public_channel(ch, argument, CHAN_WIZHELP); } void do_yell(CHAR_DATA * ch, const char *argument) { if (argument[0] == '\0') { char_puts("Yell what?\n", ch); return; } if (ch->position < POS_RESTING) return; public_channel(ch, argument, CHAN_YELL); } void do_questtalk(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_QUEST); } void do_advice(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_ADVICE); } void do_shout(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_SHOUT); } void do_music(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_MUSIC); } void do_gossip(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_GOSSIP); } void do_death_announce(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_DEATH); } void do_offer(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_TRADE); } void do_ooc(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_OOC); } void do_newbie(CHAR_DATA * ch, const char *argument) { public_channel(ch, argument, CHAN_NEWBIE); } void do_clan(CHAR_DATA * ch, const char *argument) { if (!ch->clan) { char_puts("You are not in a clan.\n", ch); return; } if (clan_lookup(ch->clan) == NULL) { char_puts("Your clan is closed.\n", ch); return; } public_channel(ch, argument, CHAN_CLAN); } void do_pray(CHAR_DATA * ch, const char *argument) { if (ch->religion == 0) { char_puts("You must first choose a god to worship.\n", ch); return; } public_channel(ch, argument, CHAN_PRAY); } void do_pose(CHAR_DATA * ch, const char *argument) { class_t *cl; pose_t *pose; int maxnum; if (IS_NPC(ch) || (cl = class_lookup(ch->class)) == NULL || cl->poses.nused == 0) return; maxnum = UMIN(ch->level, cl->poses.nused - 1); pose = VARR_GET(&cl->poses, number_range(0, maxnum)); act(pose->self, ch, NULL, NULL, TO_CHAR); act(pose->others, ch, NULL, NULL, TO_ROOM | ACT_TOBUF); } void do_bug(CHAR_DATA * ch, const char *argument) { char buf[MAX_STRING_LENGTH]; snprintf(buf, sizeof(buf), "%s [%5d] %s: %s", compact_date_str(current_time), ch->in_room ? ch->in_room->vnum : 0, ch->name, argument); if (!append_file(BUG_FILE, buf)) { char_puts ("error opening file, please report your bug to the immortals", ch); BUG("Couldn't open %s", BUG_FILE); } else char_puts("Bug logged.\n", ch); snprintf(buf, sizeof(buf), "{w[{YBUG REPORT{w]: {D[{W%5d{D] {w%s{Y:{x %s{x", ch->in_room ? ch->in_room->vnum : 0, ch->name, argument); wiznet(buf, NULL, NULL, WIZ_ANNOUNCE, 0, 0); return; } void do_typo(CHAR_DATA * ch, const char *argument) { char buf[MAX_STRING_LENGTH]; snprintf(buf, sizeof(buf), "%s [%5d] %s: %s", compact_date_str(current_time), ch->in_room ? ch->in_room->vnum : 0, ch->name, argument); if (!append_file(TYPO_FILE, buf)) { char_puts ("error opening file, please report your typo to the immortals", ch); BUG("Couldn't open %s", TYPO_FILE); } else char_puts("Typo logged.\n", ch); snprintf(buf, sizeof(buf), "{w[{YTYPO REPORT{w]: {D[{W%5d{D] {w%s{Y:{x %s{x", ch->in_room ? ch->in_room->vnum : 0, ch->name, argument); wiznet(buf, NULL, NULL, WIZ_ANNOUNCE, 0, 0); return; } void do_rent(CHAR_DATA * ch, const char *argument) { char_puts("There is no rent here. Just save and quit.\n", ch); return; } void do_qui(CHAR_DATA * ch, const char *argument) { char_puts("If you want to QUIT, you have to spell it out.\n", ch); } void do_quit(CHAR_DATA * ch, const char *argument) { if (ch->pnote) { act_puts("You have an unfinished $t in progress.", ch, flag_string(note_types, ch->pnote->type), NULL, TO_CHAR, POS_DEAD); return; } quit_char(ch, 0); } void quit_char(CHAR_DATA * ch, int flags) { DESCRIPTOR_DATA *d, *d_next; CHAR_DATA *vch, *vch_next; OBJ_DATA *obj, *obj_next, *obj_in; AFFECT_DATA *pAf = NULL; char buf[MAX_STRING_LENGTH]; int cn; const char *name; int limiteds = 0; if (IS_NPC(ch)) return; if (ch->position == POS_FIGHTING) { char_puts("No way! You are fighting.\n", ch); return; } if (ch->position < POS_STUNNED) { char_puts("You're not DEAD yet.\n", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM)) { char_puts("You don't want to leave your master.\n", ch); return; } /* if (IS_SET(ch->state_flags, STATE_NOEXP)) { char_puts("You don't want to lose your spirit.\n", ch); return; } */ if (IS_AFFECTED(ch, AFF_SLEEP)) { char_puts("You cannot quit, you are in deep sleep.\n", ch); return; } if (ch->position == POS_SLEEPING) { char_puts("In your dreams, or what?\n", ch); return; } if (auction.item != NULL && ((ch == auction.buyer) || (ch == auction.seller))) { char_puts("Wait till you have sold/bought the item " "on auction.\n", ch); return; } if (!IS_IMMORTAL(ch)) { if (IS_PUMPED(ch)) { char_puts("Your adrenaline is gushing!" " You can't quit yet.\n", ch); return; } if (is_affected(ch, gsn_witch_curse)) { char_puts("You are cursed. Wait till you DIE!\n", ch); return; } if (ch->in_room->area->clan && ch->in_room->area->clan != ch->clan) { char_puts("You can't quit here.\n", ch); return; } if (ch->in_room && IS_RAFFECTED(ch->in_room, RAFF_ESPIRIT)) { char_puts ("Evil spirits in the area prevents you from leaving.\n", ch); return; } if (!get_skill(ch, gsn_evil_spirit) && is_affected(ch, gsn_evil_spirit)) { char_puts ("Evil spirits in you prevents you from leaving.\n", ch); return; } /* count the number of limiteds the person has */ for (obj = ch->carrying; obj != NULL; obj = obj->next_content) if (IS_OBJ_LIMITED(obj->pIndexData)) limiteds++; if (limiteds > allowed_limiteds(ch->pcdata->pdata)) { char_puts("You have too many artifacts to" " journey into the astral plane.\n", ch); return; } } if (IS_SET(ch->state_flags, STATE_GHOST)) { char_puts("You return to your normal form.\n", ch); REMOVE_BIT(ch->state_flags, STATE_GHOST); REMOVE_BIT(ch->affected_by, AFF_FLYING); REMOVE_BIT(ch->affected_by, AFF_PASS_DOOR); } /* sync up the persistant data before logging off */ ch_update_usage(ch->pcdata->pdata, TRUE); sync_ch_pdata(ch); ch->pcdata->pdata->online = FALSE; char_puts("You pass into the astral plane, and feel your powers sucked away.\n", ch); act_puts("$n has passed into the astral plane.", ch, NULL, NULL, TO_ROOM, POS_RESTING); log_printf("%s has quit.", ch->name); snprintf(buf, sizeof(buf), "logout: {D$N{x - %s", (ch->desc) ? ((ch->pcdata->fake_ip) ? ch->pcdata->fake_ip : ch->desc->host) : "<no descriptor>"); wiznet(buf, ch, NULL, WIZ_LOGINS, 0, ch->level); /* * remove quest objs for this char, drop quest objs for other chars */ for (obj = object_list; obj != NULL; obj = obj_next) { obj_next = obj->next; if (obj->pIndexData->vnum >= QUEST_OBJ_FIRST && obj->pIndexData->vnum <= QUEST_OBJ_LAST) { if (obj->ed == NULL || strstr(mlstr_mval(obj->ed->description), ch->name) != NULL) extract_obj(obj, 0); else if (obj->carried_by == ch) { obj_from_char(obj); obj_to_room(obj, ch->in_room); } } if (IS_SET(obj->pIndexData->extra_flags, ITEM_CLAN) || IS_SET(obj->pIndexData->extra_flags, ITEM_QUIT_DROP) || (IS_OBJ_LIMITED(obj->pIndexData) && (obj->pIndexData->level > get_wear_level(ch, obj)))) { /* in a room */ if (obj->in_room != NULL) continue; /* if in container (obj_in) */ if ((obj_in = obj->in_obj) != NULL) { for (; obj_in->in_obj != NULL; obj_in = obj_in->in_obj); if (obj_in->carried_by != ch) continue; }; /* carried by this character */ if (obj->carried_by == ch) obj_from_char(obj); /* carried by someone else */ else if (obj->carried_by != NULL) continue; /* don't extract the auction item */ if (auction.item == obj) continue; /* extract from the container (obj_in) */ if (obj_in != NULL) obj_from_obj(obj); /* extract all limited objects that are not in the * desired range*/ if (IS_OBJ_LIMITED(obj->pIndexData) && (IS_NEWBIE(ch) || obj->pIndexData->level > get_wear_level(ch, obj))) { act_puts ("You're are unable to clutch the {mpower{x of" " $p in the astral plane, so it {Wva{wnis{Dhes{x.", ch, obj, NULL, TO_CHAR, POS_DEAD); DEBUG(DEBUG_RECLAIM, "%s[%d] reclaim limited [%d-%d/%d] [%d] %s", ch->name, ch->level, obj->pIndexData->level, obj->pIndexData->count, obj->pIndexData->limit, obj->pIndexData->vnum, obj->pIndexData->name); extract_obj(obj, 0); continue; } /* drop quit-drop items */ else if (IS_SET (obj->pIndexData->extra_flags, ITEM_QUIT_DROP)) { if (ch->in_room != NULL) obj_to_room(obj, ch->in_room); else extract_obj(obj, 0); } /* return clan items to their altars */ else for (cn = 0; cn < clans.nused; cn++) if (obj == clan_lookup(cn)->obj_ptr) obj_to_room(obj, get_room_index (clan_lookup(cn)-> altar_vnum)); } } for (vch = char_list; vch; vch = vch_next) { vch_next = vch->next; if (is_affected(vch, gsn_doppelganger) && vch->doppel == ch) { char_puts ("You shift to your true form as your victim leaves.\n", vch); affect_strip(vch, gsn_doppelganger); } /* if you log out you remove the curse from your victim */ if (is_affected(vch, gsn_witch_curse) && vch->cursed_by_witch == ch) { pAf = affect_find(vch->affected, gsn_witch_curse); affect_remove(vch, pAf); act("You feel $N's {Dcurse{x is lifted!", vch, NULL, ch, TO_CHAR); act("As you depart the realm so does the power of your curse on $N.", ch, NULL, vch, TO_CHAR); } if (vch->guarding == ch) { act("You stop guarding $N.", vch, NULL, ch, TO_CHAR); act("$n stops guarding you.", vch, NULL, ch, TO_VICT); act("$n stops guarding $N.", vch, NULL, ch, TO_NOTVICT); vch->guarding = NULL; ch->guarded_by = NULL; } if (vch->guarded_by == ch) { act("You stop guarding $N.", ch, NULL, vch, TO_CHAR); act("$n stops guarding you.", ch, NULL, vch, TO_VICT); act("$n stops guarding $N.", ch, NULL, vch, TO_NOTVICT); vch->guarded_by = NULL; ch->guarding = NULL; } if (vch->last_fought == ch) { vch->last_fought = NULL; back_home(vch); } if (vch->hunting == ch) vch->hunting = NULL; if (vch->hunter == ch) vch->hunter = NULL; if (vch->target == ch) { if (IS_NPC(vch) && vch->pIndexData->vnum == MOB_VNUM_SHADOW) { act("$n slowly fades away.", vch, NULL, NULL, TO_ROOM); extract_char(vch, 0); continue; } if (IS_NPC(vch) && vch->pIndexData->vnum == MOB_VNUM_STALKER) { if (ch->pcdata->saved_stalkers++ > 10) ch->pcdata->saved_stalkers = 10; doprintf(do_clan, vch, "%s has left the realm," " I will retire for now.", PERS(ch, vch)); act("$n slowly fades away.", vch, NULL, NULL, TO_ROOM); extract_char(vch, 0); } } } if (ch->guarded_by != NULL) { ch->guarded_by->guarding = NULL; ch->guarded_by = NULL; } /* * After extract_char the ch is no longer valid! */ save_char_obj(ch, FALSE); name = str_qdup(ch->name); d = ch->desc; extract_char(ch, flags); if (d) close_descriptor(d); /* * toast evil cheating bastards * * Workaround against clone cheat -- * Log in once, connect a second time and enter only name, * drop all and quit with first character, finish login * with second. This clones the player's inventory. */ for (d = descriptor_list; d; d = d_next) { CHAR_DATA *tch; d_next = d->next; tch = d->original ? d->original : d->character; if (tch && !str_cmp(name, tch->name)) { if (d->connected == CON_PLAYING) extract_char(tch, 0); close_descriptor(d); } } } void do_save(CHAR_DATA * ch, const char *argument) { if (IS_NPC(ch)) return; if (ch->level < 2) { char_puts("You must be at least level 2 for saving.\n", ch); return; } save_char_obj(ch, FALSE); WAIT_STATE(ch, PULSE_VIOLENCE); } void do_follow(CHAR_DATA * ch, const char *argument) { /* RT changed to allow unlimited following and follow the NOFOLLOW rules */ char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { char_puts("Follow whom?\n", ch); return; } if ((victim = get_char_room(ch, arg)) == NULL) { char_puts("They aren't here.\n", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM) && ch->master != NULL) { act("But you'd rather follow $N!", ch, NULL, ch->master, TO_CHAR); return; } if (victim == ch) { if (ch->master == NULL) { char_puts("You already follow yourself.\n", ch); return; } stop_follower(ch); return; } if (!IS_NPC(victim) && IS_SET(victim->conf_flags, PLR_CONF_NOFOLLOW) && !IS_IMMORTAL(ch)) { act("$N doesn't seem to want any followers.\n", ch, NULL, victim, TO_CHAR); return; } REMOVE_BIT(ch->conf_flags, PLR_CONF_NOFOLLOW); if (ch->master != NULL) stop_follower(ch); add_follower(ch, victim); } void add_follower(CHAR_DATA * ch, CHAR_DATA * master) { if (ch->master != NULL) { bug("Add_follower: null master.", 0); return; } ch->master = master; ch->leader = NULL; if (can_see(master, ch)) act_puts("$n now follows you.", ch, NULL, master, TO_VICT, POS_RESTING); act_puts("You now follow $N.", ch, NULL, master, TO_CHAR, POS_RESTING); } void stop_follower(CHAR_DATA * ch) { if (ch->master == NULL) { bug("Stop_follower: null master.", 0); return; } if (IS_AFFECTED(ch, AFF_CHARM)) { REMOVE_BIT(ch->affected_by, AFF_CHARM); affect_bit_strip(ch, TO_AFFECTS, AFF_CHARM); } if (can_see(ch->master, ch) && ch->in_room != NULL) { act_puts("$n stops following you.", ch, NULL, ch->master, TO_VICT, POS_RESTING); act_puts("You stop following $N.", ch, NULL, ch->master, TO_CHAR, POS_RESTING); } if (ch->master->pet == ch) ch->master->pet = NULL; ch->master = NULL; ch->leader = NULL; } /* removes all your pets from your group */ void disband_pets(CHAR_DATA * ch) { CHAR_DATA *gch; CHAR_DATA *next; AFFECT_DATA af; gch = next = npc_list; while (next) { gch = next; next = gch->next; if (IS_AFFECTED(gch, AFF_CHARM) && gch->master == ch) { stop_follower(gch); /* XXX - this doesn't work */ if (gch->position == POS_FIGHTING) { af.where = TO_AFFECTS; af.type = gsn_fear; af.level = ch->level + 10; af.duration = ch->level / 10; af.location = 0; af.modifier = 0; af.bitvector = AFF_FEAR; affect_to_char(gch, &af); } } } } /* nukes charmed monsters and pets */ void nuke_pets(CHAR_DATA * ch) { CHAR_DATA *gch; CHAR_DATA *next; gch = next = npc_list; while (next) { gch = next; next = gch->next; if (IS_AFFECTED(gch, AFF_CHARM) && gch->master == ch) { if (gch->in_room) act("$n slowly fades away.", gch, NULL, NULL, TO_ROOM); extract_char(gch, 0); } } ch->pet = NULL; } void die_follower(CHAR_DATA * ch) { CHAR_DATA *fch; CHAR_DATA *fch_next; if (ch->master != NULL) stop_follower(ch); ch->leader = NULL; for (fch = char_list; fch != NULL; fch = fch_next) { fch_next = fch->next; if (fch->master == ch) stop_follower(fch); if (fch->leader == ch) fch->leader = NULL; } } void do_order(CHAR_DATA * ch, const char *argument) { char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH]; CHAR_DATA *victim; CHAR_DATA *och; CHAR_DATA *och_next; bool found; bool fAll; argument = one_argument(argument, arg, sizeof(arg)); one_argument(argument, arg2, sizeof(arg2)); if (arg[0] == '\0' || argument[0] == '\0') { char_puts("Order whom to do what?\n", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM)) { char_puts("You feel like taking, not giving, orders.\n", ch); return; } if (is_affected(ch, gsn_rnet_trap)) { char_puts ("There's not enough room to effectively issue orders.\n", ch); return; } if (!str_cmp(arg, "all")) { fAll = TRUE; victim = NULL; } else { fAll = FALSE; if ((victim = get_char_room(ch, arg)) == NULL) { char_puts("They aren't here.\n", ch); return; } if (victim == ch) { char_puts("Aye aye, right away!\n", ch); return; } if (!IS_AFFECTED(victim, AFF_CHARM) || victim->master != ch || (IS_IMMORTAL(victim) && victim->level >= ch->level)) { char_puts("Do it yourself!\n", ch); return; } } found = FALSE; for (och = ch->in_room->people; och != NULL; och = och_next) { och_next = och->next_in_room; if (IS_AFFECTED(och, AFF_CHARM) && och->master == ch && (fAll || och == victim)) { found = TRUE; act("$n orders you to '$t'.", ch, argument, och, TO_VICT); if (!interpret_raw(och, argument, TRUE, 0)) { act("But you think better of it.", ch, argument, och, TO_VICT); act("$N can't seem to be persuaded to do that.", ch, argument, och, TO_CHAR); } } } if (found) { WAIT_STATE(ch, PULSE_VIOLENCE); char_puts("Ok.\n", ch); } else char_puts("You have no followers here.\n", ch); } CHAR_DATA *leader_lookup(CHAR_DATA * ch) { CHAR_DATA *res; for (res = ch; res->leader != NULL; res = res->leader); return res; } void do_group(CHAR_DATA * ch, const char *argument) { char arg[MAX_INPUT_LENGTH]; char format[MAX_INPUT_LENGTH]; CHAR_DATA *victim; CHAR_DATA *gch; int ansi_len = 0; one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { act_puts("$N's group:", ch, NULL, leader_lookup(ch), TO_CHAR, POS_DEAD); for (gch = char_list; gch; gch = gch->next) { if (is_same_group(gch, ch)) { ansi_len = astrlen(fix_short(PERS(gch, ch)), 30); snprintf(format, sizeof(format), "[%%1s] %%-%ds" " %%3d%%%%hp" " %%3d%%%%mana" " %%3d%%%%move " " %%7d tnl\n", 30 + ansi_len); char_printf(ch, format, (gch->level > ch->level) ? "+" : (gch->level < ch->level) ? "-" : "=", fix_short(PERS(gch, ch)), (100 * gch->hit) / UMAX(1, gch-> max_hit), (100 * gch->mana) / UMAX(1, gch-> max_mana), (100 * gch->move) / UMAX(1, gch-> max_move), IS_NPC(gch) || ch->level >= LEVEL_HERO ? 0 : exp_to_level(gch)); } } return; } if ((victim = get_char_room(ch, arg)) == NULL) { char_puts("They aren't here.\n", ch); return; } if (victim == ch) { char_puts("Huh? Grouping with yourself?!\n", ch); return; } if (ch->master != NULL || ch->leader != NULL) { char_puts("But you are following someone else!\n", ch); return; } if (victim->master != ch && ch != victim) { act("$N isn't following you.", ch, NULL, victim, TO_CHAR); return; } if (IS_AFFECTED(victim, AFF_CHARM)) { char_puts("You can't remove charmed mobs from your group.\n", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM)) { act("You like your master too much to leave $m!", ch, NULL, victim, TO_VICT); return; } if (is_same_group(victim, ch) && ch != victim) { if (ch->guarding == victim || victim->guarded_by == ch) { act("You stop guarding $N.", ch, NULL, victim, TO_CHAR); act("$n stops guarding you.", ch, NULL, victim, TO_VICT); act("$n stops guarding $N.", ch, NULL, victim, TO_NOTVICT); victim->guarded_by = NULL; ch->guarding = NULL; } victim->leader = NULL; act_puts("$n removes $N from $s group.", ch, NULL, victim, TO_NOTVICT, POS_SLEEPING); act_puts("$n removes you from $s group.", ch, NULL, victim, TO_VICT, POS_SLEEPING); act_puts("You remove $N from your group.", ch, NULL, victim, TO_CHAR, POS_SLEEPING); if (victim->guarded_by != NULL && !is_same_group(victim, victim->guarded_by)) { act("You stop guarding $N.", victim->guarded_by, NULL, victim, TO_CHAR); act("$n stops guarding you.", victim->guarded_by, NULL, victim, TO_VICT); act("$n stops guarding $N.", victim->guarded_by, NULL, victim, TO_NOTVICT); victim->guarded_by->guarding = NULL; victim->guarded_by = NULL; } return; } if (ch->level - victim->level < -8 || ch->level - victim->level > 8) { act_puts("$N cannot join $n's group.", ch, NULL, victim, TO_NOTVICT, POS_SLEEPING); act_puts("You cannot join $n's group.", ch, NULL, victim, TO_VICT, POS_SLEEPING); act_puts("$N cannot join your group.", ch, NULL, victim, TO_CHAR, POS_SLEEPING); return; } if (is_affected(ch, gsn_dishonor)) { act_puts("Regaining your honor is something you must do alone.", victim, NULL, NULL, TO_CHAR, POS_SLEEPING); return; } if (is_affected(victim, gsn_dishonor)) { act_puts("You refuse to group with a fallen samurai.", ch, NULL, NULL, TO_CHAR, POS_SLEEPING); act_puts("Your dishonorable conduct makes grouping impossible.", victim, NULL, NULL, TO_CHAR, POS_SLEEPING); return; } for (gch = char_list; gch; gch = gch->next) { if (is_same_group(gch, ch) && !IS_NPC(gch) && !(victim->clan > 0 && victim->clan == gch->clan)) { if (IS_GOOD(victim) && IS_EVIL(gch)) { act_puts ("Allying yourself with one as pure as $n disgusts you.", victim, NULL, gch, TO_VICT, POS_SLEEPING); act_puts ("Allying yourself with on as vile as $N disgusts you.", victim, NULL, gch, TO_CHAR, POS_SLEEPING); if (ch != gch) { act_puts ("Doesn't look like $N will ally with such a vile soul in the group.", ch, NULL, victim, TO_CHAR, POS_SLEEPING); } return; } if (IS_GOOD(gch) && IS_EVIL(victim)) { act_puts ("Allying yourself with one as vile as $N disgusts you.", gch, NULL, victim, TO_CHAR, POS_SLEEPING); act_puts ("Allying yourself with one as pure as $n disgusts you.", gch, NULL, victim, TO_VICT, POS_SLEEPING); if (ch != gch) { act_puts ("Doesn't look like $N will ally with such a pure soul in the group.", ch, NULL, victim, TO_CHAR, POS_SLEEPING); } return; } if ((HAS_SKILL(victim, gsn_ruler_badge) && HAS_SKILL(gch, gsn_disperse)) || (HAS_SKILL(victim, gsn_disperse) && HAS_SKILL(gch, gsn_ruler_badge)) || (HAS_SKILL(victim, gsn_evil_spirit) && HAS_SKILL(gch, gsn_riding)) || (HAS_SKILL(victim, gsn_riding) && HAS_SKILL(gch, gsn_evil_spirit)) || (HAS_SKILL(victim, gsn_mastering_spell) && HAS_SKILL(gch, gsn_spellbane)) || (HAS_SKILL(victim, gsn_spellbane) && HAS_SKILL(gch, gsn_mastering_spell))) { act_puts ("You hate $n's clan, how can you join $n's group?", victim, NULL, gch, TO_VICT, POS_SLEEPING); act_puts ("You hate $N's clan, how can you want $N to join your group", victim, NULL, gch, TO_CHAR, POS_SLEEPING); if (ch != gch) { act_puts ("Looks like $N has something against someone in your group.", ch, NULL, victim, TO_CHAR, POS_SLEEPING); } return; } } } victim->leader = ch; act_puts("$N joins $n's group.", ch, NULL, victim, TO_NOTVICT, POS_SLEEPING); act_puts("You join $n's group.", ch, NULL, victim, TO_VICT, POS_SLEEPING); act_puts("$N joins your group.", ch, NULL, victim, TO_CHAR, POS_SLEEPING); } /* * 'Split' originally by Gnort, God of Chaos. */ void do_split(CHAR_DATA * ch, const char *argument) { char buf[MAX_STRING_LENGTH]; char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH]; CHAR_DATA *gch; int members; int amount_gold = 0, amount_silver = 0; int share_gold, share_silver; int extra_gold, extra_silver; argument = one_argument(argument, arg1, sizeof(arg1)); one_argument(argument, arg2, sizeof(arg2)); if (arg1[0] == '\0') { char_puts("Split how much?\n", ch); return; } amount_silver = atoi(arg1); if (arg2[0] != '\0') amount_gold = atoi(arg2); if (amount_gold < 0 || amount_silver < 0) { char_puts("Your group wouldn't like that.\n", ch); return; } if (amount_gold == 0 && amount_silver == 0) { char_puts("You hand out zero coins, but no one notices.\n", ch); return; } if (ch->gold < amount_gold || ch->silver < amount_silver) { char_puts("You don't have that much to split.\n", ch); return; } members = 0; for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room) { if (is_same_group(gch, ch) && !IS_AFFECTED(gch, AFF_CHARM)) members++; } if (members < 2) { char_puts("Just keep it all.\n", ch); return; } share_silver = amount_silver / members; extra_silver = amount_silver % members; share_gold = amount_gold / members; extra_gold = amount_gold % members; if (share_gold == 0 && share_silver == 0) { char_puts("Don't even bother, cheapskate.\n", ch); return; } ch->silver -= amount_silver; ch->silver += share_silver + extra_silver; ch->gold -= amount_gold; ch->gold += share_gold + extra_gold; if (share_silver > 0) char_printf(ch, "You split %d silver coins. Your share is %d silver.\n", amount_silver, share_silver + extra_silver); if (share_gold > 0) char_printf(ch, "You split %d gold coins. Your share is %d gold.\n", amount_gold, share_gold + extra_gold); if (share_gold == 0) snprintf(buf, sizeof(buf), "$n splits %d silver coins. Your share is %d silver.", amount_silver, share_silver); else if (share_silver == 0) snprintf(buf, sizeof(buf), "$n splits %d gold coins. Your share is %d gold.", amount_gold, share_gold); else snprintf(buf, sizeof(buf), "$n splits %d silver and %d gold coins, giving you %d silver and %d gold.\n", amount_silver, amount_gold, share_silver, share_gold); for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room) { if (gch != ch && is_same_group(gch, ch) && !IS_AFFECTED(gch, AFF_CHARM)) { act(buf, ch, NULL, gch, TO_VICT); gch->gold += share_gold; gch->silver += share_silver; } } return; } void do_speak(CHAR_DATA * ch, const char *argument) { char arg[MAX_INPUT_LENGTH]; int language; race_t *r; if (IS_NPC(ch) || (r = race_lookup(ch->pcdata->race)) == NULL || !r->pcdata) return; argument = one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { char_printf(ch, "You now speak %s.\n", flag_string(slang_table, ch->slang)); char_puts("You can speak :\n", ch); char_printf(ch, " common, %s\n", flag_string(slang_table, r->pcdata->slang)); return; } if ((language = flag_value(slang_table, arg)) < 0 || language >= SLANG_MAX) { char_puts("You never heard of that language.\n", ch); return; } if (IS_NPC(ch) || IS_IMMORTAL(ch)) ch->slang = language; else if (language != SLANG_COMMON && language != r->pcdata->slang) { char_puts("But you don't speak that language!\n", ch); return; } else ch->slang = language; char_printf(ch, "Now you speak %s.\n", flag_string(slang_table, ch->slang)); } DO_FUN(do_twit) { char arg[MAX_STRING_LENGTH]; if (IS_NPC(ch)) { char_puts("Huh?\n", ch); return; } one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { char_printf(ch, "Current twitlist is [%s]\n", ch->pcdata->twitlist); return; } name_toggle(&ch->pcdata->twitlist, arg, ch, "Twitlist"); } DO_FUN(do_lang) { char arg[MAX_STRING_LENGTH]; int lang; lang_t *l; if (langs.nused == 0) { char_puts("No languages defined.\n", ch); return; } argument = one_argument(argument, arg, sizeof(arg)); if (*arg == '\0') { l = varr_get(&langs, ch->lang); if (l == NULL) { log_printf("do_lang: %s: lang == %d\n", ch->name, ch->lang); l = VARR_GET(&langs, ch->lang = 0); } char_printf(ch, "Interface language is '%s'.\n", l->name); return; } lang = lang_lookup(arg); if (lang < 0) { char_puts("Usage: lang [ ", ch); for (lang = 0; lang < langs.nused; lang++) { l = VARR_GET(&langs, lang); if (IS_SET(l->flags, LANG_HIDDEN)) continue; char_printf(ch, "%s%s", lang == 0 ? str_empty : " | ", l->name); } char_puts(" ]\n", ch); return; } ch->lang = lang; do_lang(ch, str_empty); do_look(ch, str_empty); } DO_FUN(do_judge) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; if (!HAS_SKILL(ch, gsn_ruler_badge)) { char_puts("Huh?\n", ch); return; } argument = one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { char_puts("Judge whom?\n", ch); return; } if ((victim = get_char_world(ch, arg)) == NULL) { char_puts("They aren't here.\n", ch); return; } if (IS_NPC(victim)) { char_puts("Not a mobile, of course.\n", ch); return; } if (IS_IMMORTAL(victim) && !IS_IMMORTAL(ch)) { char_puts("You do not have the power to judge Immortals.\n", ch); return; } char_printf(ch, "%s is %s-%s.\n", PERS(victim, ch), flag_string(ethos_table, victim->ethos), flag_string(align_names, NALIGN(victim))); } DO_FUN(do_trust) { char arg[MAX_INPUT_LENGTH]; if (IS_NPC(ch)) { char_puts("Huh?\n", ch); return; } one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { if (!ch->pcdata->trust) { char_puts ("You do not allow anyone to cast questionable spells on you.\n", ch); return; } if (IS_SET(ch->pcdata->trust, TRUST_ALL)) { char_puts ("You allow everyone to cast questionable spells on you.\n", ch); return; } if (IS_SET(ch->pcdata->trust, TRUST_CLAN)) char_puts ("You trust your clan with questionable spells.\n", ch); if (IS_SET(ch->pcdata->trust, TRUST_GROUP)) char_puts ("You trust your group with questionable spells.\n", ch); if (IS_SET(ch->pcdata->trust, TRUST_GOOD)) char_puts ("You trust angelic souls with questionable spells.\n", ch); if (IS_SET(ch->pcdata->trust, TRUST_NEUTRAL)) char_puts ("You trust balanced souls with questionable spells.\n", ch); if (IS_SET(ch->pcdata->trust, TRUST_EVIL)) char_puts ("You trust demonic souls with questionable spells.\n", ch); return; } if (!str_cmp(arg, "clan")) { if (ch->clan == 0) { char_puts("You are not in clan.\n", ch); return; }; TOGGLE_BIT(ch->pcdata->trust, TRUST_CLAN); if (IS_SET(ch->pcdata->trust, TRUST_CLAN)) { REMOVE_BIT(ch->pcdata->trust, TRUST_ALL); char_puts ("You now trust your clan with questionable spells.\n", ch); } else char_puts ("You no longer trust your clan with questionable spells.\n", ch); return; } if (!str_cmp(arg, "group")) { TOGGLE_BIT(ch->pcdata->trust, TRUST_GROUP); if (IS_SET(ch->pcdata->trust, TRUST_GROUP)) { REMOVE_BIT(ch->pcdata->trust, TRUST_ALL); char_puts ("You allow your group to cast questionable spells on you.\n", ch); } else char_puts ("You no longer trust your group with questionable spells.\n", ch); return; } if (!str_cmp(arg, "good")) { TOGGLE_BIT(ch->pcdata->trust, TRUST_GOOD); if (IS_SET(ch->pcdata->trust, TRUST_GOOD)) { REMOVE_BIT(ch->pcdata->trust, TRUST_ALL); char_puts ("You allow your angelic souls to cast questionable spells on you.\n", ch); } else char_puts ("You no longer trust angelic souls with questionable spells.\n", ch); return; } if (!str_cmp(arg, "neutral")) { TOGGLE_BIT(ch->pcdata->trust, TRUST_NEUTRAL); if (IS_SET(ch->pcdata->trust, TRUST_NEUTRAL)) { REMOVE_BIT(ch->pcdata->trust, TRUST_ALL); char_puts ("You allow your balanced souls to cast questionable spells on you.\n", ch); } else char_puts ("You no longer trust balanced souls with questionable spells.\n", ch); return; } if (!str_cmp(arg, "evil")) { TOGGLE_BIT(ch->pcdata->trust, TRUST_EVIL); if (IS_SET(ch->pcdata->trust, TRUST_EVIL)) { REMOVE_BIT(ch->pcdata->trust, TRUST_ALL); char_puts ("You allow your demonic souls to cast questionable spells on you.\n", ch); } else char_puts ("You no longer trust demonic souls with questionable spells.\n", ch); return; } if (!str_cmp(arg, "all")) { ch->pcdata->trust = TRUST_ALL; char_puts ("You allow everyone to cast questionable spells on you.\n", ch); return; } if (!str_cmp(arg, "none")) { ch->pcdata->trust = 0; char_puts ("You do not allow anyone to cast questionable spells on you.\n", ch); return; } char_puts ("Syntax: trust {{ group | clan | good | neutral | evil | all | none }\n", ch); } DO_FUN(do_manacle) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; AFFECT_DATA af; int sn_manacle; AFFECT_DATA *paf; AFFECT_DATA *paf_next; if ((sn_manacle = sn_lookup("manacle")) < 0 || get_skill(ch, sn_manacle) == 0) { char_puts("Huh?\n", ch); return; } argument = one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { char_puts("Toggle manacle whom?\n", ch); return; } if ((victim = get_char_room(ch, arg)) == NULL) { char_puts("They aren't here.\n", ch); return; } if (IS_IMMORTAL(victim) && ch->level < victim->level) { act("Immortals cannot be criminals.", ch, NULL, victim, TO_CHAR); return; } if (victim == ch) { char_puts("You cannot do that to yourself.\n", ch); return; } if (IS_SET(victim->state_flags, STATE_WANTED)) { TOGGLE_BIT(victim->state_flags, STATE_MANACLE); if (IS_SET(victim->state_flags, STATE_MANACLE)) { act("Manacles have been slapped around $n's wrists!!!", victim, NULL, ch, TO_ROOM); char_puts ("Manacles have been slapped around your wrists!!!\n", victim); af.where = TO_AFFECTS; af.type = sn_manacle; af.level = ch->level; af.duration = (ch->level) / 3; af.location = APPLY_STR; af.modifier = -1 * ((ch->level) / 3); af.bitvector = 0; affect_to_char(victim, &af); char_puts ("You feel your strength slipping as the manacles tighten around your wrists.\n", victim); act("$n looks like his strength is slipping as the manacles tighten around his wrists.", victim, NULL, NULL, TO_ROOM); af.where = TO_AFFECTS; af.type = sn_manacle; af.level = ch->level; af.duration = (ch->level) / 3; af.location = APPLY_DEX; af.modifier = -1 * ((ch->level) / 3); af.bitvector = 0; affect_to_char(victim, &af); char_puts ("You feel the manacles begin to hinder your movements.\n", victim); act("$n looks as if the manacles have begun hindering his movements.", victim, NULL, NULL, TO_ROOM); af.where = TO_AFFECTS; af.type = sn_manacle; af.level = ch->level; af.duration = (ch->level) / 3; af.location = APPLY_HITROLL; af.modifier = -1 * (ch->level); af.bitvector = 0; affect_to_char(victim, &af); char_puts ("You feel the manacles hindering your accuracy.\n", victim); act("$n looks as if the manacles have begun hindering his accuracy.", victim, NULL, NULL, TO_ROOM); af.where = TO_AFFECTS; af.type = sn_manacle; af.level = ch->level; af.duration = (ch->level) / 3; af.location = APPLY_DAMROLL; af.modifier = -1 * (ch->level); af.bitvector = 0; affect_to_char(victim, &af); char_puts ("You feel the manacles hinder your battle prowress.\n", victim); act("$n looks as if the manacles have begun hindering battle prowress.", victim, NULL, NULL, TO_ROOM); af.where = TO_AFFECTS; af.type = sn_manacle; af.level = ch->level; af.duration = (ch->level) / 3; af.location = APPLY_AC; af.modifier = 4 * (ch->level); af.bitvector = 0; affect_to_char(victim, &af); char_puts("You feel like a much easier target.\n", victim); act("$n looks like a much easier target.", victim, NULL, NULL, TO_ROOM); return; } else { act("The manacles have been removed from $n's wrists.", victim, NULL, ch, TO_ROOM); char_puts ("The manacles have been removed from your wrists.\n", victim); for (paf = victim->affected; paf; paf = paf_next) { paf_next = paf->next; if (paf->type == sn_manacle) affect_remove(victim, paf); } return; } char_puts("They must be criminals to be manacled.\n", ch); } char_puts("They must be criminals to be manacled.\n", ch); } DO_FUN(do_wanted) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int sn_wanted; if ((sn_wanted = sn_lookup("wanted")) < 0 || get_skill(ch, sn_wanted) == 0) { char_puts("Huh?\n", ch); return; } argument = one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { char_puts("Toggle wanted whom?\n", ch); return; } if ((victim = get_char_world(ch, arg)) == NULL) { char_puts("They aren't here.\n", ch); return; } if (IS_NPC(victim)) { char_puts("Not a mobile, of course.\n", ch); return; } if (IS_IMMORTAL(victim) && ch->level < victim->level) { act("You do not have the power to arrest $N.", ch, NULL, victim, TO_CHAR); return; } if (victim == ch) { char_puts("You cannot do that to yourself.\n", ch); return; } TOGGLE_BIT(victim->state_flags, STATE_WANTED); if (IS_SET(victim->state_flags, STATE_WANTED)) { act("$n is now WANTED!!!", victim, NULL, ch, TO_NOTVICT); act("$n is now WANTED!!!", victim, NULL, ch, TO_VICT); char_puts("You are now WANTED!!!\n", victim); } else { act("$n is no longer wanted.", victim, NULL, ch, TO_NOTVICT); act("$n is no longer wanted.", victim, NULL, ch, TO_VICT); char_puts("You are no longer wanted.\n", victim); } } /*----------------------------------------------------------------------------- * toggle bit stuff */ typedef struct toggle_t toggle_t; struct toggle_t { const char *name; /* flag name */ const char *desc; /* toggle description */ flag_t *f; /* flag table */ flag64_t bit; /* flag bit */ const char *msg_on; /* msg to print when flag toggled on */ const char *msg_off; /* ---//--- off */ }; static toggle_t *toggle_lookup(const char *name); static void toggle_print(CHAR_DATA * ch, toggle_t * t); static flag64_t *toggle_bits(CHAR_DATA * ch, toggle_t * t); /* * alphabetize these table by name if you are adding new entries */ toggle_t toggle_table[] = { /* *INDENT-OFF* */ { "affects", "show affects in score", comm_flags, COMM_SHOWAFF, "Affects will now be shown in score.", "Affects will no longer be shown in score." }, { "brief", "brief descriptions", comm_flags, COMM_BRIEF, "Short descriptions activated.", "Full descriptions activated." }, { "color", "ANSI colors", comm_flags, COMM_COLOR, "{BC{Ro{Yl{Co{Gr{x is now {RON{x, Way Cool!", "Color is now OFF, *sigh*" }, { "compact", "compact mode", comm_flags, COMM_COMPACT, "$t set.", "$t removed." }, { "combine", "combined items in inventory list", comm_flags, COMM_COMBINE, "Combined inventory selected.", "Long inventory selected." }, { "long flags", "long flags mode", comm_flags, COMM_LONG, "$t set.", "$t removed." }, { "nobust", "do not bust prompt if hp/mana/move changed", comm_flags, COMM_NOBUST, "$t set.", "$t removed." }, { "noeng", "do not display english obj/mob names", comm_flags, COMM_NOENG, "You will not see english obj/mob names anymore.", "You will now see english obj/mob names." }, { "noflee", "do not flee from combat in lost-link", comm_flags, COMM_NOFLEE, "You will not flee automagically from combat in lost-link anymore.", "You will flee automagically from combat in lost-link." }, { "notelnet", "no telnet parser", comm_flags, COMM_NOTELNET, "Telnet parser is OFF.", "Telnet parser is ON.", }, { "noiac", "no IACs in output", comm_flags, COMM_NOIAC, "IACs will not be sent to you anymore.", "Text will be sent to you unmodified.", }, { "noverbose", "no verbose messages", comm_flags, COMM_NOVERBOSE, "You will no longer see verbose messages.", "Now you will see verbose messages." }, { "prompt", "show prompt", comm_flags, COMM_PROMPT, "You will now see prompts.", "You will no longer see prompts." }, { "telnet GA", "send IAC GA (goahead) after each prompt", comm_flags, COMM_TELNET_GA, "IAC GA will be sent after each prompt.", "IAC GA will not be sent after prompts.", }, { "quiet edit", "quiet mode in string editor", comm_flags, COMM_QUIET_EDITOR, "$t set.", "$t removed." }, { "helper", "offer to help newbies in need", plr_conf_flags, PLR_CONF_NEWBIE_HELPER, "$t set. Do not offensively PK. You may help newbies in OOC ways.", "$t removed. You can go back to PKing. You are bound by your normal RP." }, { "newbie", "newbie protection, a trial account for new players", acct_flags, ACCT_NEWBIE, "$t set. You are now in newbie-protected mode. You cannot PK or be PKed.", "$t removed. You can now join a clan, hold artifacts, PK and be PKed." }, { "true lifer", "one life, one death.{x", acct_flags, ACCT_TRUE_LIFER, "None of this resurrection crap for you.", "You are no longer a true lifer . . . wimp!" }, { "multikiller", "forsake multikill rules {D- {rthis cannot be turned off{x", acct_flags, ACCT_MULTIKILLER, "You may now ignore the multikill rules with other multikillers {RONLY{x.", "You must abide the multikill rules with all players." }, { NULL } /* *INDENT-ON* */ }; DO_FUN(do_toggle) { toggle_t *t; char arg[MAX_INPUT_LENGTH]; argument = one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { char_puts("Your current settings are:\n", ch); for (t = toggle_table; t->name; t++) toggle_print(ch, t); return; } for (; arg[0]; argument = one_argument(argument, arg, sizeof(arg))) { flag64_t *bits; if ((t = toggle_lookup(arg)) == NULL || (bits = toggle_bits(ch, t)) == NULL) { char_printf(ch, "%s: no such toggle.\n", arg); continue; } if (!IS_IMMORTAL(ch) && t->f == acct_flags && t->bit == ACCT_NEWBIE) { char_puts("Newbie protection cannot be turned off," " you must remake your character.\n", ch); continue; } if (!IS_IMMORTAL(ch) && t->f == acct_flags && t->bit == ACCT_MULTIKILLER && IS_SET(ch->acct_flags, ACCT_MULTIKILLER)) { char_puts("Once a multi-killer always a multi-killer.\n", ch); continue; } if (!IS_IMMORTAL(ch) && t->f == acct_flags && t->bit == ACCT_TRUE_LIFER) { if (IS_SET(ch->acct_flags, ACCT_TRUE_LIFER)) char_puts("Only one way out. This ain't it.\n", ch); else char_puts("This is only selectable at creation.\n", ch); continue; } if (IS_IMMORTAL(ch) && ch->level < ML && t->f == acct_flags && t->bit == ACCT_TRUE_LIFER) { char_puts("Uhm, yeah. Whatever.\n", ch); continue; } if (!IS_IMMORTAL(ch) && t->f == acct_flags && t->bit == ACCT_MULTIKILLER && !IS_SET(ch->acct_flags, ACCT_MULTIKILLER)) { wiznet("$N is now a {rmultikiller{x.", ch, NULL, WIZ_ANNOUNCE, 0, 0); LOG("%s is now a multikiller", ch->name); } TOGGLE_BIT(*bits, t->bit); act_puts(IS_SET(*bits, t->bit) ? t->msg_on : t->msg_off, ch, t->desc, NULL, TO_CHAR | ACT_TRANS, POS_DEAD); } } static toggle_t *toggle_lookup(const char *name) { toggle_t *t; for (t = toggle_table; t->name; t++) if (!str_prefix(name, t->name)) break; return t; } static void toggle_print(CHAR_DATA * ch, toggle_t * t) { char buf[MAX_STRING_LENGTH]; flag64_t *bits; if ((bits = toggle_bits(ch, t)) < 0) return; snprintf(buf, sizeof(buf), " %-11.11s {D-{x %-7.7s ($t)", t->name, IS_SET(*bits, t->bit) ? "{GON{x" : "{ROFF{x"); act_puts(buf, ch, t->desc, NULL, TO_CHAR | ACT_TRANS, POS_DEAD); } static flag64_t *toggle_bits(CHAR_DATA * ch, toggle_t * t) { if (t->f == comm_flags) return &ch->comm; if (t->f == acct_flags) return &ch->acct_flags; if (t->f == state_flags) return &ch->state_flags; if (t->f == plr_conf_flags) return &ch->conf_flags; return NULL; }