/** * @file act_other.c * @ingroup common * * Miscellaneous player-level commands * * @author Part of CircleMUD * * @par Copyright: * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University<br> * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * * @par * All rights reserved. See license.doc for complete information. * * @package cs * @version 1.0 */ #define __ACT_OTHER_C__ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "character.h" #include "comm.h" #include "command.h" #include "interpreter.h" #include "handler.h" #include "db.h" #include "spells.h" #include "screen.h" #include "house.h" #include "constants.h" #include "log.h" #include "zone.h" #include "item.h" #include "room.h" #include "mobile.h" /* extern variables */ extern spellData_t spell_info[]; extern const char *class_abbrevs[]; extern int free_rent; extern int pt_allowed; extern int max_filesize; extern int nameserver_is_slow; extern int auto_save; extern int track_through_doors; /* extern procedures */ void list_skills(charData_t *ch); void appear(charData_t *ch); void write_aliases(charData_t *ch); void perform_immort_vis(charData_t *ch); SPECIAL(shop_keeper); void die(charData_t *ch); void Crash_rentsave(charData_t *ch, int cost); /* local functions */ int perform_group(charData_t *ch, charData_t *vict); void print_group(charData_t *ch); /** * QUIT command * * This command lets a user exit the game * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_quit) { if (IS_NPC(ch) || !ch->desc) return; if (CMD_IS("qui") && GET_AUTH(ch) < AUTH_WIZARD) send_to_char(ch, "You have to type quit--no less, to quit!\r\n"); else if (GET_POS(ch) == POS_FIGHTING) send_to_char(ch, "No way! You're fighting for your life!\r\n"); else if (GET_POS(ch) < POS_STUNNED) { send_to_char(ch, "You die before your time...\r\n"); die(ch); } else { act("$n has left the game.", TRUE, ch, 0, 0, TO_ROOM); mudlog(NRM, MAX(AUTH_WIZARD, GET_INVIS_AUTH(ch)), TRUE, "%s has quit the game.", GET_NAME(ch)); send_to_char(ch, "Goodbye, friend.. Come back soon!\r\n"); /* We used to check here for duping attempts, but we may as well * do it right in char_extract(), since there is no check if a * player rents out and it can leave them in an equally screwy * situation. */ if (free_rent) Crash_rentsave(ch, 0); /* If someone is quitting in their house, let them load back here. */ if (!PLR_FLAGGED(ch, PLR_LOADROOM) && ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOUSE)) GET_LOADROOM(ch) = IN_ROOM(ch); char_extract(ch); /* Char is saved before extracting. */ } } /** * SAVE command * * This command lets a user save their data * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_save) { if (IS_NPC(ch) || !ch->desc) return; /* Only tell the char we're saving if they actually typed "save" */ if (cmd) { /* * This prevents item duplication by two PC's using coordinated saves * (or one PC with a house) and system crashes. Note that houses are * still automatically saved without this enabled. This code assumes * that guest immortals aren't trustworthy. If you've disabled guest * immortal advances from mortality, you may want < instead of <=. */ if (auto_save && GET_AUTH(ch) < AUTH_WIZARD) { send_to_char(ch, "Saving aliases.\r\n"); write_aliases(ch); return; } send_to_char(ch, "Saving %s and aliases.\r\n", GET_NAME(ch)); } write_aliases(ch); save_char(ch); Crash_crashsave(ch); if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOUSE_CRASH)) House_crashsave(IN_ROOM(ch)); } /** * Generic Function used for spec_procs * * This command is overridden by spec_proc commands. If it's not * overridden then the user will get the "you can't do that here" * message. * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_not_here) { send_to_char(ch, "Sorry, but you cannot do that here!\r\n"); } /** * SNEAK command * * This command lets a user attempt to move silently * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none * @sa SKILL_SNEAK * @sa AFF_SNEAK */ ACMD(do_sneak) { effectData_t af; byte percent; if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_SNEAK)) { send_to_char(ch, "You have no idea how to do that.\r\n"); return; } send_to_char(ch, "Okay, you'll try to move silently for a while.\r\n"); if (AFF_FLAGGED(ch, AFF_SNEAK)) effectData_fromChar(ch, SKILL_SNEAK); percent = rand_number(1, 101); /* 101% is a complete failure */ if (percent > GET_SKILL(ch, SKILL_SNEAK) + dex_app_skill[GET_DEX(ch)].sneak) return; af.type = SKILL_SNEAK; af.duration = GET_LEVEL(ch); af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_SNEAK; effectData_toChar(ch, &af); } /** * HIDE command * * This command lets a user attempt to hide from sight * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none * @sa SKILL_HIDE * @sa AFF_HIDE */ ACMD(do_hide) { byte percent; if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_HIDE)) { send_to_char(ch, "You have no idea how to do that.\r\n"); return; } send_to_char(ch, "You attempt to hide yourself.\r\n"); if (AFF_FLAGGED(ch, AFF_HIDE)) REMOVE_BIT(AFF_FLAGS(ch), AFF_HIDE); percent = rand_number(1, 101); /* 101% is a complete failure */ if (percent > GET_SKILL(ch, SKILL_HIDE) + dex_app_skill[GET_DEX(ch)].hide) return; SET_BIT(AFF_FLAGS(ch), AFF_HIDE); } /** * STEAL command * * This command lets a user attempt to steal * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none * @sa SKILL_STEAL */ ACMD(do_steal) { charData_t *vict; itemData_t *obj; char vict_name[MAX_INPUT_LENGTH], obj_name[MAX_INPUT_LENGTH]; int percent, gold, eq_pos, pcsteal = 0, ohoh = 0; if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_STEAL)) { send_to_char(ch, "You have no idea how to do that.\r\n"); return; } if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n"); return; } two_arguments(argument, obj_name, vict_name); if (!(vict = get_char_vis(ch, vict_name, NULL, FIND_CHAR_ROOM))) { send_to_char(ch, "Steal what from who?\r\n"); return; } else if (vict == ch) { send_to_char(ch, "Come on now, that's rather stupid!\r\n"); return; } /* 101% is a complete failure */ percent = rand_number(1, 101) - dex_app_skill[GET_DEX(ch)].p_pocket; if (GET_POS(vict) < POS_SLEEPING) percent = -1; /* ALWAYS SUCCESS, unless heavy object. */ if (!pt_allowed && !IS_NPC(vict)) pcsteal = 1; if (!AWAKE(vict)) /* Easier to steal from sleeping people. */ percent -= 50; /* NO NO With Imp's and Shopkeepers, and if player thieving is not allowed */ if (GET_AUTH(vict) >= AUTH_WIZARD || pcsteal) /* || GET_MOB_SPEC(vict) == shop_keeper) */ /* World Convert - FIX */ percent = 101; /* Failure */ if (str_cmp(obj_name, "coins") && str_cmp(obj_name, "gold")) { if (!(obj = get_item_in_list_vis(ch, obj_name, NULL, vict->carrying))) { for (eq_pos = 0; eq_pos < NUM_WEARS; eq_pos++) if (GET_EQ(vict, eq_pos) && (isname(obj_name, GET_EQ(vict, eq_pos)->name)) && CAN_SEE_ITEM(ch, GET_EQ(vict, eq_pos))) { obj = GET_EQ(vict, eq_pos); break; } if (!obj) { act("$E hasn't got that item.", FALSE, ch, 0, vict, TO_CHAR); return; } else { /* It is equipment */ if ((GET_POS(vict) > POS_STUNNED)) { send_to_char(ch, "Steal the equipment now? Impossible!\r\n"); return; } else { act("You unequip $p and steal it.", FALSE, ch, obj, 0, TO_CHAR); act("$n steals $p from $N.", FALSE, ch, obj, vict, TO_NOTVICT); itemData_toChar(char_unequipItem(vict, eq_pos), ch); } } } else { /* obj found in inventory */ percent += GET_ITEM_WEIGHT(obj); /* Make heavy harder */ if (percent > GET_SKILL(ch, SKILL_STEAL)) { ohoh = TRUE; send_to_char(ch, "Oops..\r\n"); act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT); act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT); } else { /* Steal the item */ if (IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch)) { if (IS_CARRYING_W(ch) + GET_ITEM_WEIGHT(obj) < CAN_CARRY_W(ch)) { itemData_fromChar(obj); itemData_toChar(obj, ch); send_to_char(ch, "Got it!\r\n"); } } else send_to_char(ch, "You cannot carry that much.\r\n"); } } } else { /* Steal some coins */ if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) { ohoh = TRUE; send_to_char(ch, "Oops..\r\n"); act("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, vict, TO_VICT); act("$n tries to steal gold from $N.", TRUE, ch, 0, vict, TO_NOTVICT); } else { /* Steal some gold coins */ gold = (GET_GOLD(vict) * rand_number(1, 10)) / 100; gold = MIN(1782, gold); if (gold > 0) { GET_GOLD(ch) += gold; GET_GOLD(vict) -= gold; if (gold > 1) send_to_char(ch, "Bingo! You got %d gold coins.\r\n", gold); else send_to_char(ch, "You manage to swipe a solitary gold coin.\r\n"); } else { send_to_char(ch, "You couldn't get any gold...\r\n"); } } } if (ohoh && IS_NPC(vict) && AWAKE(vict)) hit(vict, ch, TYPE_UNDEFINED); } /** * PRACTICE command * * This command lets a user attempt to improve a specified skill * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_practice) { char arg[MAX_INPUT_LENGTH]; if (IS_NPC(ch)) return; one_argument(argument, arg); if (*arg) send_to_char(ch, "You can only practice skills in your guild.\r\n"); else list_skills(ch); } /** * VISIBLE command * * This command lets a user become visible * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none * @sa AFF_INVISIBLE */ ACMD(do_visible) { if (GET_AUTH(ch) >= AUTH_WIZARD) { perform_immort_vis(ch); return; } if AFF_FLAGGED(ch, AFF_INVISIBLE) { appear(ch); send_to_char(ch, "You break the spell of invisibility.\r\n"); } else send_to_char(ch, "You are already visible.\r\n"); } /** * TITLE command * * This command lets a user specify a title * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_title) { skip_spaces(&argument); delete_doubledollar(argument); if (IS_NPC(ch)) send_to_char(ch, "Your title is fine... go away.\r\n"); else if (PLR_FLAGGED(ch, PLR_NOTITLE)) send_to_char(ch, "You can't title yourself -- you shouldn't have abused it!\r\n"); else if (strstr(argument, "(") || strstr(argument, ")")) send_to_char(ch, "Titles can't contain the ( or ) characters.\r\n"); else if (strlen(argument) > MAX_TITLE_LENGTH) send_to_char(ch, "Sorry, titles can't be longer than %d characters.\r\n", MAX_TITLE_LENGTH); else { set_title(ch, argument); send_to_char(ch, "Okay, you're now %s %s.\r\n", GET_NAME(ch), GET_TITLE(ch)); } } /** * Group a character to another * * @param ch Character to lead the group * @param vict Character to add to the group * @return TRUE or FALSE * @todo Update to bool instead of int * @sa AFF_GROUP */ int perform_group(charData_t *ch, charData_t *vict) { if (AFF_FLAGGED(vict, AFF_GROUP) || !CAN_SEE(ch, vict)) return (0); SET_BIT(AFF_FLAGS(vict), AFF_GROUP); if (ch != vict) act("$N is now a member of your group.", FALSE, ch, 0, vict, TO_CHAR); act("You are now a member of $n's group.", FALSE, ch, 0, vict, TO_VICT); act("$N is now a member of $n's group.", FALSE, ch, 0, vict, TO_NOTVICT); return (1); } /** * Display the members of a group * * @param ch Character to whom to send the output * @returns none * @sa AFF_GROUP */ void print_group(charData_t *ch) { charData_t *k; followData_t *f; if (!AFF_FLAGGED(ch, AFF_GROUP)) send_to_char(ch, "But you are not the member of a group!\r\n"); else { char buf[MAX_STRING_LENGTH]; send_to_char(ch, "Your group consists of:\r\n"); k = (ch->master ? ch->master : ch); if (AFF_FLAGGED(k, AFF_GROUP)) { snprintf(buf, sizeof(buf), " [%3dH %3dM %3dV] [%2d %s] $N (Head of group)", GET_HIT(k), GET_MANA(k), GET_MOVE(k), GET_LEVEL(k), CLASS_ABBR(k)); act(buf, FALSE, ch, 0, k, TO_CHAR); } for (f = k->followers; f; f = f->next) { if (!AFF_FLAGGED(f->follower, AFF_GROUP)) continue; snprintf(buf, sizeof(buf), " [%3dH %3dM %3dV] [%2d %s] $N", GET_HIT(f->follower), GET_MANA(f->follower), GET_MOVE(f->follower), GET_LEVEL(f->follower), CLASS_ABBR(f->follower)); act(buf, FALSE, ch, 0, f->follower, TO_CHAR); } } } /** * GROUP command * * This command lets a user create a group of characters * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none * @sa AFF_GROUP */ ACMD(do_group) { char buf[MAX_STRING_LENGTH]; charData_t *vict; followData_t *f; int found; one_argument(argument, buf); if (!*buf) { print_group(ch); return; } if (ch->master) { act("You can not enroll group members without being head of a group.", FALSE, ch, 0, 0, TO_CHAR); return; } if (!str_cmp(buf, "all")) { perform_group(ch, ch); for (found = 0, f = ch->followers; f; f = f->next) found += perform_group(ch, f->follower); if (!found) send_to_char(ch, "Everyone following you is already in your group.\r\n"); return; } if (!(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM))) send_to_char(ch, "%s", NOPERSON); else if ((vict->master != ch) && (vict != ch)) act("$N must follow you to enter your group.", FALSE, ch, 0, vict, TO_CHAR); else { if (!AFF_FLAGGED(vict, AFF_GROUP)) perform_group(ch, vict); else { if (ch != vict) act("$N is no longer a member of your group.", FALSE, ch, 0, vict, TO_CHAR); act("You have been kicked out of $n's group!", FALSE, ch, 0, vict, TO_VICT); act("$N has been kicked out of $n's group!", FALSE, ch, 0, vict, TO_NOTVICT); REMOVE_BIT(AFF_FLAGS(vict), AFF_GROUP); } } } /** * UNGROUP command * * This command lets a user disband a group of characters * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none * @sa AFF_GROUP * @sa AFF_CHARM */ ACMD(do_ungroup) { char buf[MAX_INPUT_LENGTH]; followData_t *f, *next_fol; charData_t *tch; one_argument(argument, buf); if (!*buf) { if (ch->master || !(AFF_FLAGGED(ch, AFF_GROUP))) { send_to_char(ch, "But you lead no group!\r\n"); return; } for (f = ch->followers; f; f = next_fol) { next_fol = f->next; if (AFF_FLAGGED(f->follower, AFF_GROUP)) { REMOVE_BIT(AFF_FLAGS(f->follower), AFF_GROUP); act("$N has disbanded the group.", TRUE, f->follower, NULL, ch, TO_CHAR); if (!AFF_FLAGGED(f->follower, AFF_CHARM)) stop_follower(f->follower); } } REMOVE_BIT(AFF_FLAGS(ch), AFF_GROUP); send_to_char(ch, "You disband the group.\r\n"); return; } if (!(tch = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM))) { send_to_char(ch, "There is no such person!\r\n"); return; } if (tch->master != ch) { send_to_char(ch, "That person is not following you!\r\n"); return; } if (!AFF_FLAGGED(tch, AFF_GROUP)) { send_to_char(ch, "That person isn't in your group.\r\n"); return; } REMOVE_BIT(AFF_FLAGS(tch), AFF_GROUP); act("$N is no longer a member of your group.", FALSE, ch, 0, tch, TO_CHAR); act("You have been kicked out of $n's group!", FALSE, ch, 0, tch, TO_VICT); act("$N has been kicked out of $n's group!", FALSE, ch, 0, tch, TO_NOTVICT); if (!AFF_FLAGGED(tch, AFF_CHARM)) stop_follower(tch); } /** * REPORT command * * This command lets a user report their stats to other group members * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none * @sa AFF_GROUP */ ACMD(do_report) { char buf[MAX_STRING_LENGTH]; charData_t *k; followData_t *f; if (!AFF_FLAGGED(ch, AFF_GROUP)) { send_to_char(ch, "But you are not a member of any group!\r\n"); return; } snprintf(buf, sizeof(buf), "$n reports: %d/%dH, %d/%dM, %d/%dV\r\n", GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch), GET_MOVE(ch), GET_MAX_MOVE(ch)); k = (ch->master ? ch->master : ch); for (f = k->followers; f; f = f->next) if (AFF_FLAGGED(f->follower, AFF_GROUP) && f->follower != ch) act(buf, TRUE, ch, NULL, f->follower, TO_VICT); if (k != ch) act(buf, TRUE, ch, NULL, k, TO_VICT); send_to_char(ch, "You report to the group.\r\n"); } /** * SPLIT command * * This command lets a user split gold with group members * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none * @sa AFF_GROUP */ ACMD(do_split) { char buf[MAX_INPUT_LENGTH]; int amount, num, share, rest; size_t len; charData_t *k; followData_t *f; if (IS_NPC(ch)) return; one_argument(argument, buf); if (isInteger(buf, FALSE)) { amount = atoi(buf); if (amount <= 0) { send_to_char(ch, "Sorry, you can't do that.\r\n"); return; } if (amount > GET_GOLD(ch)) { send_to_char(ch, "You don't seem to have that much gold to split.\r\n"); return; } k = (ch->master ? ch->master : ch); if (AFF_FLAGGED(k, AFF_GROUP) && (IN_ROOM(k) == IN_ROOM(ch))) num = 1; else num = 0; for (f = k->followers; f; f = f->next) if (AFF_FLAGGED(f->follower, AFF_GROUP) && (!IS_NPC(f->follower)) && (IN_ROOM(f->follower) == IN_ROOM(ch))) num++; if (num && AFF_FLAGGED(ch, AFF_GROUP)) { share = amount / num; rest = amount % num; } else { send_to_char(ch, "With whom do you wish to share your gold?\r\n"); return; } GET_GOLD(ch) -= share * (num - 1); /* Abusing signed/unsigned to make sizeof work. */ len = snprintf(buf, sizeof(buf), "%s splits %d coins; you receive %d.\r\n", GET_NAME(ch), amount, share); if (rest && len < sizeof(buf)) { snprintf(buf + len, sizeof(buf) - len, "%d coin%s %s not splitable, so %s keeps the money.\r\n", rest, (rest == 1) ? "" : "s", (rest == 1) ? "was" : "were", GET_NAME(ch)); } if (AFF_FLAGGED(k, AFF_GROUP) && IN_ROOM(k) == IN_ROOM(ch) && !IS_NPC(k) && k != ch) { GET_GOLD(k) += share; send_to_char(k, "%s", buf); } for (f = k->followers; f; f = f->next) { if (AFF_FLAGGED(f->follower, AFF_GROUP) && (!IS_NPC(f->follower)) && (IN_ROOM(f->follower) == IN_ROOM(ch)) && f->follower != ch) { GET_GOLD(f->follower) += share; send_to_char(f->follower, "%s", buf); } } send_to_char(ch, "You split %d coins among %d members -- %d coins each.\r\n", amount, num, share); if (rest) { send_to_char(ch, "%d coin%s %s not splitable, so you keep the money.\r\n", rest, (rest == 1) ? "" : "s", (rest == 1) ? "was" : "were"); GET_GOLD(ch) += rest; } } else { send_to_char(ch, "How many coins do you wish to split with your group?\r\n"); return; } } /** * USE, RECITE, QUAFF commands * * These commands allow a user to use special objects * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_use) { char buf[MAX_INPUT_LENGTH], arg[MAX_INPUT_LENGTH]; itemData_t *mag_item; half_chop(argument, arg, buf); if (!*arg) { send_to_char(ch, "What do you want to %s?\r\n", CMD_NAME); return; } mag_item = GET_EQ(ch, WEAR_HOLD); if (!mag_item || !isname(arg, mag_item->name)) { if (CMD_IS("recite") || CMD_IS("quaff")) { if (!(mag_item = get_item_in_list_vis(ch, arg, NULL, ch->carrying))) { send_to_char(ch, "You don't seem to have %s %s.\r\n", AN(arg), arg); return; } } else if (CMD_IS("use")) { send_to_char(ch, "You don't seem to be holding %s %s.\r\n", AN(arg), arg); } else { log("SYSERR: Unknown command '%s' passed to do_use.", CMD_NAME); } } if (CMD_IS("quaff")) { if (GET_ITEM_TYPE(mag_item) != ITEM_POTION) { send_to_char(ch, "You can only quaff potions.\r\n"); return; } } else if (CMD_IS("recite")) { if (GET_ITEM_TYPE(mag_item) != ITEM_SCROLL) { send_to_char(ch, "You can only recite scrolls.\r\n"); return; } } else if (CMD_IS("use")) { if ((GET_ITEM_TYPE(mag_item) != ITEM_WAND) && (GET_ITEM_TYPE(mag_item) != ITEM_STAFF)) { send_to_char(ch, "You can't seem to figure out how to use it.\r\n"); return; } } mag_objectmagic(ch, mag_item, buf); } /** * WIMPY command * * This command lets a user specify a point that they'll attempt to automatically flee * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_wimpy) { char arg[MAX_INPUT_LENGTH]; int wimp_lev; /* 'wimp_level' is a player_special. -gg 2/25/98 */ if (IS_NPC(ch)) return; one_argument(argument, arg); if (!*arg) { if (GET_WIMP_LEV(ch)) { send_to_char(ch, "Your current wimp level is %d hit points.\r\n", GET_WIMP_LEV(ch)); return; } else { send_to_char(ch, "At the moment, you're not a wimp. (sure, sure...)\r\n"); return; } } if (isdigit(*arg)) { if ((wimp_lev = atoi(arg)) != 0) { if (wimp_lev < 0) send_to_char(ch, "Heh, heh, heh.. we are jolly funny today, eh?\r\n"); else if (wimp_lev > GET_MAX_HIT(ch)) send_to_char(ch, "That doesn't make much sense, now does it?\r\n"); else if (wimp_lev > (GET_MAX_HIT(ch) / 2)) send_to_char(ch, "You can't set your wimp level above half your hit points.\r\n"); else { send_to_char(ch, "Okay, you'll wimp out if you drop below %d hit points.\r\n", wimp_lev); GET_WIMP_LEV(ch) = wimp_lev; } } else { send_to_char(ch, "Okay, you'll now tough out fights to the bitter end.\r\n"); GET_WIMP_LEV(ch) = 0; } } else send_to_char(ch, "Specify at how many hit points you want to wimp out at. (0 to disable)\r\n"); } /** * DISPLAY command * * This command lets a user specify options to display in their prompt * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_display) { size_t i; if (IS_NPC(ch)) { send_to_char(ch, "Mosters don't need displays. Go away.\r\n"); return; } skip_spaces(&argument); if (!*argument) { send_to_char(ch, "Usage: prompt { { H | M | V } | all | auto | none }\r\n"); return; } if (!str_cmp(argument, "auto")) { TOGGLE_BIT(PRF_FLAGS(ch), PRF_DISPAUTO); send_to_char(ch, "Auto prompt %sabled.\r\n", PRF_FLAGGED(ch, PRF_DISPAUTO) ? "en" : "dis"); return; } if (!str_cmp(argument, "on") || !str_cmp(argument, "all")) SET_BIT(PRF_FLAGS(ch), PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE); else if (!str_cmp(argument, "off") || !str_cmp(argument, "none")) REMOVE_BIT(PRF_FLAGS(ch), PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE); else { REMOVE_BIT(PRF_FLAGS(ch), PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE); for (i = 0; i < strlen(argument); i++) { switch (LOWER(argument[i])) { case 'h': SET_BIT(PRF_FLAGS(ch), PRF_DISPHP); break; case 'm': SET_BIT(PRF_FLAGS(ch), PRF_DISPMANA); break; case 'v': SET_BIT(PRF_FLAGS(ch), PRF_DISPMOVE); break; default: send_to_char(ch, "Usage: prompt { { H | M | V } | all | auto | none }\r\n"); return; } } } send_to_char(ch, "%s", OK); } /** * BUG, IDEA, TYPO commands * * This command lets a user report bugs, ideas, or typos * * @param ch the character performing the command * @param argument the additional text passed after the command * @param cmd the command object that was performed * @returns none */ ACMD(do_gen_write) { FILE *fl; char *tmp; const char *filename; struct stat fbuf; time_t ct; if (CMD_IS("bug")) filename = BUG_FILE; else if (CMD_IS("typo")) filename = TYPO_FILE; else if (CMD_IS("idea")) filename = IDEA_FILE; else return; ct = time(0); tmp = asctime(localtime(&ct)); if (IS_NPC(ch)) { send_to_char(ch, "Monsters can't have ideas - Go away.\r\n"); return; } skip_spaces(&argument); delete_doubledollar(argument); if (!*argument) { send_to_char(ch, "That must be a mistake...\r\n"); return; } mudlog(CMP, AUTH_WIZARD, FALSE, "%s %s: %s", GET_NAME(ch), CMD_NAME, argument); if (stat(filename, &fbuf) < 0) { perror("SYSERR: Can't stat() file"); return; } if (fbuf.st_size >= max_filesize) { send_to_char(ch, "Sorry, the file is full right now.. try again later.\r\n"); return; } if (!(fl = fopen(filename, "a"))) { perror("SYSERR: do_gen_write"); send_to_char(ch, "Could not open the file. Sorry.\r\n"); return; } fprintf(fl, "%-8s (%6.6s) [%s:%d] %s\n", GET_NAME(ch), (tmp + 4), IN_ROOM(ch)->zone->keyword, IN_ROOM(ch)->number, argument); fclose(fl); send_to_char(ch, "Okay. Thanks!\r\n"); }