tbamud/src/act.informative.c
Rumble d0db332492 [Apr 14 2007] - Rumble
IP's only visible to LVL_GOD and above now for the paranoid people out there.
[Apr 13 2007] - Rumble
 Finally made gemote actually work like emote and not just use socials. (thanks Fizban)
 Reworded and standardized the trigedit attachment menu.
 Numerous minor fixes taken from the latest CWG release. (thanks Zizazat)
 Update to is_number to check for negative numbers. (thanks Kyle)
 Update to isname to disallow abbreviated numbers. (thanks Sryth)
[Apr 08 2007] - Rumble
 Removed all usage of CAP(str causing a memory leak (thanks Kyle).
2007-04-14 00:44:52 +00:00

2214 lines
66 KiB
C

/**************************************************************************
* File: act.informative.c Part of tbaMUD *
* Usage: Player-level commands of an informative nature. *
* *
* All rights reserved. See license for complete information. *
* *
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
**************************************************************************/
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
#include "screen.h"
#include "constants.h"
#include "dg_scripts.h"
/* extern variables */
extern int top_of_h_table;
extern struct help_index_element *help_table;
extern char *help;
extern char *ihelp;
extern struct time_info_data time_info;
extern char *credits;
extern char *news;
extern char *info;
extern char *motd;
extern char *imotd;
extern char *wizlist;
extern char *immlist;
extern char *policies;
extern char *handbook;
extern char *class_abbrevs[];
/* extern functions */
ACMD(do_action);
bitvector_t find_class_bitvector(const char *arg);
int level_exp(int chclass, int level);
char *title_male(int chclass, int level);
char *title_female(int chclass, int level);
struct time_info_data *real_time_passed(time_t t2, time_t t1);
int compute_armor_class(struct char_data *ch);
int has_mail(long id);
/* local functions */
int sort_commands_helper(const void *a, const void *b);
void print_object_location(int num, struct obj_data *obj, struct char_data *ch, int recur);
void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mode);
void list_obj_to_char(struct obj_data *list, struct char_data *ch, int mode, int show);
void show_obj_modifiers(struct obj_data *obj, struct char_data *ch);
ACMD(do_look);
ACMD(do_examine);
ACMD(do_gold);
ACMD(do_score);
ACMD(do_inventory);
ACMD(do_equipment);
ACMD(do_time);
ACMD(do_weather);
void space_to_minus(char *str);
ACMD(do_help);
ACMD(do_who);
ACMD(do_users);
ACMD(do_gen_ps);
void perform_mortal_where(struct char_data *ch, char *arg);
void perform_immort_where(struct char_data *ch, char *arg);
ACMD(do_where);
ACMD(do_levels);
ACMD(do_consider);
ACMD(do_diagnose);
ACMD(do_color);
ACMD(do_toggle);
void sort_commands(void);
ACMD(do_commands);
void diag_char_to_char(struct char_data *i, struct char_data *ch);
void look_at_char(struct char_data *i, struct char_data *ch);
void list_one_char(struct char_data *i, struct char_data *ch);
void list_char_to_char(struct char_data *list, struct char_data *ch);
void do_auto_exits(struct char_data *ch);
ACMD(do_exits);
void look_in_direction(struct char_data *ch, int dir);
void look_in_obj(struct char_data *ch, char *arg);
char *find_exdesc(char *word, struct extra_descr_data *list);
void look_at_target(struct char_data *ch, char *arg);
/* local globals */
int *cmd_sort_info;
/* For show_obj_to_char 'mode'. /-- arbitrary */
#define SHOW_OBJ_LONG 0
#define SHOW_OBJ_SHORT 1
#define SHOW_OBJ_ACTION 2
void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mode)
{
int found = 0;
struct char_data *temp;
if (!obj || !ch) {
log("SYSERR: NULL pointer in show_obj_to_char(): obj=%p ch=%p", obj, ch);
/* SYSERR_DESC: Somehow a NULL pointer was sent to show_obj_to_char() in
* either the 'obj' or the 'ch' variable. The error will indicate which
* was NULL by listing both of the pointers passed to it. This is often a
* difficult one to trace, and may require stepping through a debugger. */
return;
}
if ((mode == 0) && obj->description) {
if (!GET_OBJ_VAL(obj, 1) == 0 || OBJ_SAT_IN_BY(obj)) {
temp = OBJ_SAT_IN_BY(obj);
for (temp = OBJ_SAT_IN_BY(obj); temp; temp = NEXT_SITTING(temp)) {
if (temp == ch)
found++;
}
if (found) {
send_to_char(ch, "You are %s upon %s.", GET_POS(ch) == POS_SITTING ? "sitting" :
"resting", obj->short_description);
goto end;
}
}
}
switch (mode) {
case SHOW_OBJ_LONG:
/* Hide objects starting with . from non-holylighted people. - Elaseth */
if (*obj->description == '.' && (IS_NPC(ch) || !PRF_FLAGGED(ch, PRF_HOLYLIGHT)))
return;
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS))
send_to_char(ch, "[%d] %s", GET_OBJ_VNUM(obj), SCRIPT(obj) ? "[TRIG] " : "");
send_to_char(ch, "%s", CCGRN(ch, C_NRM));
send_to_char(ch, "%s", obj->description);
break;
case SHOW_OBJ_SHORT:
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS))
send_to_char(ch, "[%d] %s", GET_OBJ_VNUM(obj), SCRIPT(obj) ? "[TRIG] " : "");
send_to_char(ch, "%s", obj->short_description);
break;
case SHOW_OBJ_ACTION:
switch (GET_OBJ_TYPE(obj)) {
case ITEM_NOTE:
if (obj->action_description) {
char notebuf[MAX_NOTE_LENGTH + 64];
snprintf(notebuf, sizeof(notebuf), "There is something written on it:\r\n\r\n%s", obj->action_description);
page_string(ch->desc, notebuf, TRUE);
} else
send_to_char(ch, "It's blank.\r\n");
return;
case ITEM_DRINKCON:
send_to_char(ch, "It looks like a drink container.");
break;
default:
send_to_char(ch, "You see nothing special..");
break;
}
break;
default:
log("SYSERR: Bad display mode (%d) in show_obj_to_char().", mode);
/* SYSERR_DESC: show_obj_to_char() has some predefined 'mode's (argument
* #3) to tell it what to display to the character when it is called. If
* the mode is not one of these, it will output this error, and indicate
* what mode was passed to it. To correct it, you will need to find the
* call with the incorrect mode and change it to an acceptable mode. */
return;
}
end:
show_obj_modifiers(obj, ch);
send_to_char(ch, "\r\n");
}
void show_obj_modifiers(struct obj_data *obj, struct char_data *ch)
{
if (OBJ_FLAGGED(obj, ITEM_INVISIBLE))
send_to_char(ch, " (invisible)");
if (OBJ_FLAGGED(obj, ITEM_BLESS) && AFF_FLAGGED(ch, AFF_DETECT_ALIGN))
send_to_char(ch, " ..It glows blue!");
if (OBJ_FLAGGED(obj, ITEM_MAGIC) && AFF_FLAGGED(ch, AFF_DETECT_MAGIC))
send_to_char(ch, " ..It glows yellow!");
if (OBJ_FLAGGED(obj, ITEM_GLOW))
send_to_char(ch, " ..It has a soft glowing aura!");
if (OBJ_FLAGGED(obj, ITEM_HUM))
send_to_char(ch, " ..It emits a faint humming sound!");
}
void list_obj_to_char(struct obj_data *list, struct char_data *ch, int mode, int show)
{
struct obj_data *i, *j;
bool found;
int num;
found = FALSE;
for (i = list; i; i = i->next_content) {
num = 0;
for (j = list; j != i; j = j->next_content)
if (!strcmp(j->short_description, i->short_description))
break;
if (j != i)
continue;
for (j = i; j; j = j->next_content)
if (!strcmp(j->short_description, i->short_description))
num++;
if (CAN_SEE_OBJ(ch, i) && (*i->description != '.' || (IS_NPC(ch) || PRF_FLAGGED(ch, PRF_HOLYLIGHT)))) {
if (mode == SHOW_OBJ_LONG)
send_to_char(ch, "%s", CCGRN(ch, C_NRM));
if (num != 1)
send_to_char(ch, "(%2i) ", num);
show_obj_to_char(i, ch, mode);
send_to_char(ch, "%s", CCNRM(ch, C_NRM));
found = TRUE;
}
}
if (!found && show)
send_to_char(ch, " Nothing.\r\n");
}
void diag_char_to_char(struct char_data *i, struct char_data *ch)
{
struct {
byte percent;
const char *text;
} diagnosis[] = {
{ 100, "is in excellent condition." },
{ 90, "has a few scratches." },
{ 75, "has some small wounds and bruises." },
{ 50, "has quite a few wounds." },
{ 30, "has some big nasty wounds and scratches." },
{ 15, "looks pretty hurt." },
{ 0, "is in awful condition." },
{ -1, "is bleeding awfully from big wounds." },
};
int percent, ar_index;
const char *pers = PERS(i, ch);
if (GET_MAX_HIT(i) > 0)
percent = (100 * GET_HIT(i)) / GET_MAX_HIT(i);
else
percent = -1; /* How could MAX_HIT be < 1?? */
for (ar_index = 0; diagnosis[ar_index].percent >= 0; ar_index++)
if (percent >= diagnosis[ar_index].percent)
break;
send_to_char(ch, "%c%s %s\r\n", UPPER(*pers), pers + 1, diagnosis[ar_index].text);
}
void look_at_char(struct char_data *i, struct char_data *ch)
{
int j, found;
struct obj_data *tmp_obj;
if (!ch->desc)
return;
if (i->player.description)
send_to_char(ch, "%s", i->player.description);
else
act("You see nothing special about $m.", FALSE, i, 0, ch, TO_VICT);
diag_char_to_char(i, ch);
found = FALSE;
for (j = 0; !found && j < NUM_WEARS; j++)
if (GET_EQ(i, j) && CAN_SEE_OBJ(ch, GET_EQ(i, j)))
found = TRUE;
if (found) {
send_to_char(ch, "\r\n"); /* act() does capitalization. */
act("$n is using:", FALSE, i, 0, ch, TO_VICT);
for (j = 0; j < NUM_WEARS; j++)
if (GET_EQ(i, j) && CAN_SEE_OBJ(ch, GET_EQ(i, j))) {
send_to_char(ch, "%s", wear_where[j]);
show_obj_to_char(GET_EQ(i, j), ch, SHOW_OBJ_SHORT);
}
}
if (ch != i && (IS_THIEF(ch) || GET_LEVEL(ch) >= LVL_IMMORT)) {
found = FALSE;
act("\r\nYou attempt to peek at $s inventory:", FALSE, i, 0, ch, TO_VICT);
for (tmp_obj = i->carrying; tmp_obj; tmp_obj = tmp_obj->next_content) {
if (CAN_SEE_OBJ(ch, tmp_obj) && (rand_number(0, 20) < GET_LEVEL(ch))) {
show_obj_to_char(tmp_obj, ch, SHOW_OBJ_SHORT);
found = TRUE;
}
}
if (!found)
send_to_char(ch, "You can't see anything.\r\n");
}
}
void list_one_char(struct char_data *i, struct char_data *ch)
{
struct obj_data *furniture;
const char *positions[] = {
" is lying here, dead.",
" is lying here, mortally wounded.",
" is lying here, incapacitated.",
" is lying here, stunned.",
" is sleeping here.",
" is resting here.",
" is sitting here.",
"!FIGHTING!",
" is standing here."
};
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS) && IS_NPC(i))
send_to_char(ch, "[%d] %s", GET_MOB_VNUM(i), SCRIPT(i) ? "[TRIG] " : "");
if (IS_NPC(i) && i->player.long_descr && GET_POS(i) == GET_DEFAULT_POS(i)) {
if (AFF_FLAGGED(i, AFF_INVISIBLE))
send_to_char(ch, "*");
if (AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) {
if (IS_EVIL(i))
send_to_char(ch, "(Red Aura) ");
else if (IS_GOOD(i))
send_to_char(ch, "(Blue Aura) ");
}
send_to_char(ch, "%s", i->player.long_descr);
if (AFF_FLAGGED(i, AFF_SANCTUARY))
act("...$e glows with a bright light!", FALSE, i, 0, ch, TO_VICT);
if (AFF_FLAGGED(i, AFF_BLIND))
act("...$e is groping around blindly!", FALSE, i, 0, ch, TO_VICT);
return;
}
if (IS_NPC(i))
send_to_char(ch, "%c%s", UPPER(*i->player.short_descr), i->player.short_descr + 1);
else
send_to_char(ch, "%s%s%s", i->player.name, *GET_TITLE(i) ? " " : "", GET_TITLE(i));
if (AFF_FLAGGED(i, AFF_INVISIBLE))
send_to_char(ch, " (invisible)");
if (AFF_FLAGGED(i, AFF_HIDE))
send_to_char(ch, " (hidden)");
if (!IS_NPC(i) && !i->desc)
send_to_char(ch, " (linkless)");
if (!IS_NPC(i) && PLR_FLAGGED(i, PLR_WRITING))
send_to_char(ch, " (writing)");
if (!IS_NPC(i) && PRF_FLAGGED(i, PRF_BUILDWALK))
send_to_char(ch, " (buildwalk)");
if (!IS_NPC(i) && PRF_FLAGGED(i, PRF_AFK))
send_to_char(ch, " (AFK)");
if (GET_POS(i) != POS_FIGHTING) {
if (!SITTING(i))
send_to_char(ch, "%s", positions[(int) GET_POS(i)]);
else {
furniture = SITTING(i);
send_to_char(ch, " is %s upon %s.", (GET_POS(i) == POS_SLEEPING ?
"sleeping" : (GET_POS(i) == POS_RESTING ? "resting" : "sitting")),
OBJS(furniture, ch));
}
} else {
if (FIGHTING(i)) {
send_to_char(ch, " is here, fighting ");
if (FIGHTING(i) == ch)
send_to_char(ch, "YOU!");
else {
if (IN_ROOM(i) == IN_ROOM(FIGHTING(i)))
send_to_char(ch, "%s!", PERS(FIGHTING(i), ch));
else
send_to_char(ch, "someone who has already left!");
}
} else /* NIL fighting pointer */
send_to_char(ch, " is here struggling with thin air.");
}
if (AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) {
if (IS_EVIL(i))
send_to_char(ch, " (Red Aura)");
else if (IS_GOOD(i))
send_to_char(ch, " (Blue Aura)");
}
send_to_char(ch, "\r\n");
if (AFF_FLAGGED(i, AFF_SANCTUARY))
act("...$e glows with a bright light!", FALSE, i, 0, ch, TO_VICT);
}
void list_char_to_char(struct char_data *list, struct char_data *ch)
{
struct char_data *i;
for (i = list; i; i = i->next_in_room)
if (ch != i) {
/* hide npcs whose description starts with a '.' from non-holylighted people - Idea from Elaseth of TBA */
if (!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT) &&
IS_NPC(i) && i->player.long_descr && *i->player.long_descr == '.')
continue;
send_to_char(ch, "%s", CCYEL(ch, C_NRM));
if (CAN_SEE(ch, i))
list_one_char(i, ch);
else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch) &&
AFF_FLAGGED(i, AFF_INFRAVISION))
send_to_char(ch, "You see a pair of glowing red eyes looking your way.\r\n");
send_to_char(ch, "%s", CCNRM(ch, C_NRM));
}
}
void do_auto_exits(struct char_data *ch)
{
int door, slen = 0;
send_to_char(ch, "%s[ Exits: ", CCCYN(ch, C_NRM));
for (door = 0; door < NUM_OF_DIRS; door++) {
if (!EXIT(ch, door) || EXIT(ch, door)->to_room == NOWHERE)
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))
continue;
send_to_char(ch, "%c ", LOWER(*dirs[door]));
slen++;
}
send_to_char(ch, "%s]%s\r\n", slen ? "" : "None!", CCNRM(ch, C_NRM));
}
ACMD(do_exits)
{
int door, len = 0;
if (AFF_FLAGGED(ch, AFF_BLIND)) {
send_to_char(ch, "You can't see a damned thing, you're blind!\r\n");
return;
}
send_to_char(ch, "Obvious exits:\r\n");
for (door = 0; door < NUM_OF_DIRS; door++) {
if (!EXIT(ch, door) || EXIT(ch, door)->to_room == NOWHERE)
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))
continue;
len++;
if (PRF_FLAGGED(ch, PRF_SHOWVNUMS))
send_to_char(ch, "%-5s - [%5d] %s\r\n", dirs[door], GET_ROOM_VNUM(EXIT(ch, door)->to_room),
world[EXIT(ch, door)->to_room].name);
else
send_to_char(ch, "%-5s - %s\r\n", dirs[door], IS_DARK(EXIT(ch, door)->to_room) &&
!CAN_SEE_IN_DARK(ch) ? "Too dark to tell." : world[EXIT(ch, door)->to_room].name);
}
if (!len)
send_to_char(ch, " None.\r\n");
}
void look_at_room(struct char_data *ch, int ignore_brief)
{
struct room_data *rm = &world[IN_ROOM(ch)];
if (!ch->desc)
return;
if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) {
send_to_char(ch, "It is pitch black...\r\n");
return;
} else if (AFF_FLAGGED(ch, AFF_BLIND)) {
send_to_char(ch, "You see nothing but infinite darkness...\r\n");
return;
}
send_to_char(ch, "%s", CCCYN(ch, C_NRM));
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS)) {
char buf[MAX_STRING_LENGTH];
sprintbit(ROOM_FLAGS(IN_ROOM(ch)), room_bits, buf, sizeof(buf));
send_to_char(ch, "[%5d] ", GET_ROOM_VNUM(IN_ROOM(ch)));
send_to_char(ch, "%s%s [ %s]",
SCRIPT(rm) ? "[TRIG] " : "",
world[IN_ROOM(ch)].name, buf);
} else
send_to_char(ch, "%s", world[IN_ROOM(ch)].name);
send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief ||
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH))
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
/* autoexits */
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
do_auto_exits(ch);
/* now list characters & objects */
list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE);
list_char_to_char(world[IN_ROOM(ch)].people, ch);
}
void look_in_direction(struct char_data *ch, int dir)
{
if (EXIT(ch, dir)) {
if (EXIT(ch, dir)->general_description)
send_to_char(ch, "%s", EXIT(ch, dir)->general_description);
else
send_to_char(ch, "You see nothing special.\r\n");
if (EXIT_FLAGGED(EXIT(ch, dir), EX_CLOSED) && EXIT(ch, dir)->keyword)
send_to_char(ch, "The %s is closed.\r\n", fname(EXIT(ch, dir)->keyword));
else if (EXIT_FLAGGED(EXIT(ch, dir), EX_ISDOOR) && EXIT(ch, dir)->keyword)
send_to_char(ch, "The %s is open.\r\n", fname(EXIT(ch, dir)->keyword));
} else
send_to_char(ch, "Nothing special there...\r\n");
}
void look_in_obj(struct char_data *ch, char *arg)
{
struct obj_data *obj = NULL;
struct char_data *dummy = NULL;
int amt, bits;
if (!*arg)
send_to_char(ch, "Look in what?\r\n");
else if (!(bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM |
FIND_OBJ_EQUIP, ch, &dummy, &obj))) {
send_to_char(ch, "There doesn't seem to be %s %s here.\r\n", AN(arg), arg);
} else if ((GET_OBJ_TYPE(obj) != ITEM_DRINKCON) &&
(GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) &&
(GET_OBJ_TYPE(obj) != ITEM_CONTAINER))
send_to_char(ch, "There's nothing inside that!\r\n");
else {
if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) {
if (OBJVAL_FLAGGED(obj, CONT_CLOSED))
send_to_char(ch, "It is closed.\r\n");
else {
send_to_char(ch, "%s", fname(obj->name));
switch (bits) {
case FIND_OBJ_INV:
send_to_char(ch, " (carried): \r\n");
break;
case FIND_OBJ_ROOM:
send_to_char(ch, " (here): \r\n");
break;
case FIND_OBJ_EQUIP:
send_to_char(ch, " (used): \r\n");
break;
}
list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE);
}
} else { /* item must be a fountain or drink container */
if (GET_OBJ_VAL(obj, 1) <= 0)
send_to_char(ch, "It is empty.\r\n");
else {
if (GET_OBJ_VAL(obj, 0) < 0)
{
char buf2[MAX_STRING_LENGTH];
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's full of a %s liquid.\r\n", buf2);
}
else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0))
send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */
else {
char buf2[MAX_STRING_LENGTH];
amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0);
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2);
}
}
}
}
}
char *find_exdesc(char *word, struct extra_descr_data *list)
{
struct extra_descr_data *i;
for (i = list; i; i = i->next)
if (*i->keyword == '.' ? isname(word, i->keyword + 1) : isname(word, i->keyword))
return (i->description);
return (NULL);
}
/* Given the argument "look at <target>", figure out what object or char
* matches the target. First, see if there is another char in the room with
* the name. Then check local objs for exdescs. Thanks to Angus Mezick for
* the suggested fix to this problem. */
void look_at_target(struct char_data *ch, char *arg)
{
int bits, found = FALSE, j, fnum, i = 0;
struct char_data *found_char = NULL;
struct obj_data *obj, *found_obj = NULL;
char *desc;
if (!ch->desc)
return;
if (!*arg) {
send_to_char(ch, "Look at what?\r\n");
return;
}
bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP |
FIND_CHAR_ROOM, ch, &found_char, &found_obj);
/* Is the target a character? */
if (found_char != NULL) {
look_at_char(found_char, ch);
if (ch != found_char) {
if (CAN_SEE(found_char, ch))
act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT);
act("$n looks at $N.", TRUE, ch, 0, found_char, TO_NOTVICT);
}
return;
}
/* Strip off "number." from 2.foo and friends. */
if (!(fnum = get_number(&arg))) {
send_to_char(ch, "Look at what?\r\n");
return;
}
/* Does the argument match an extra desc in the room? */
if ((desc = find_exdesc(arg, world[IN_ROOM(ch)].ex_description)) != NULL && ++i == fnum) {
page_string(ch->desc, desc, FALSE);
return;
}
/* Does the argument match an extra desc in the char's equipment? */
for (j = 0; j < NUM_WEARS && !found; j++)
if (GET_EQ(ch, j) && CAN_SEE_OBJ(ch, GET_EQ(ch, j)))
if ((desc = find_exdesc(arg, GET_EQ(ch, j)->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
}
/* Does the argument match an extra desc in the char's inventory? */
for (obj = ch->carrying; obj && !found; obj = obj->next_content) {
if (CAN_SEE_OBJ(ch, obj))
if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
}
}
/* Does the argument match an extra desc of an object in the room? */
for (obj = world[IN_ROOM(ch)].contents; obj && !found; obj = obj->next_content)
if (CAN_SEE_OBJ(ch, obj))
if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
}
/* If an object was found back in generic_find */
if (bits) {
if (!found)
show_obj_to_char(found_obj, ch, SHOW_OBJ_ACTION);
else {
show_obj_modifiers(found_obj, ch);
send_to_char(ch, "\r\n");
}
} else if (!found)
send_to_char(ch, "You do not see that here.\r\n");
}
ACMD(do_look)
{
int look_type;
int found = 0;
if (!ch->desc)
return;
if (GET_POS(ch) < POS_SLEEPING)
send_to_char(ch, "You can't see anything but stars!\r\n");
else if (AFF_FLAGGED(ch, AFF_BLIND))
send_to_char(ch, "You can't see a damned thing, you're blind!\r\n");
else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) {
send_to_char(ch, "It is pitch black...\r\n");
list_char_to_char(world[IN_ROOM(ch)].people, ch); /* glowing red eyes */
} else {
char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
half_chop(argument, arg, arg2);
if (subcmd == SCMD_READ) {
if (!*arg)
send_to_char(ch, "Read what?\r\n");
else
look_at_target(ch, arg);
return;
}
if (!*arg) /* "look" alone, without an argument at all */
look_at_room(ch, 1);
else if (is_abbrev(arg, "in"))
look_in_obj(ch, arg2);
/* did the char type 'look <direction>?' */
else if ((look_type = search_block(arg, dirs, FALSE)) >= 0)
look_in_direction(ch, look_type);
else if (is_abbrev(arg, "at"))
look_at_target(ch, arg2);
else if (is_abbrev(arg, "around")) {
struct extra_descr_data *i;
for (i = world[IN_ROOM(ch)].ex_description; i; i = i->next) {
if (*i->keyword != '.') {
send_to_char(ch, "%s%s:\r\n%s",
(found ? "\r\n" : ""), i->keyword, i->description);
found = 1;
}
}
if (!found)
send_to_char(ch, "You couldn't find anything noticeable.\r\n");
} else
look_at_target(ch, arg);
}
}
ACMD(do_examine)
{
struct char_data *tmp_char;
struct obj_data *tmp_object;
char tempsave[MAX_INPUT_LENGTH], arg[MAX_INPUT_LENGTH];
one_argument(argument, arg);
if (!*arg) {
send_to_char(ch, "Examine what?\r\n");
return;
}
/* look_at_target() eats the number. */
look_at_target(ch, strcpy(tempsave, arg)); /* strcpy: OK */
generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_CHAR_ROOM |
FIND_OBJ_EQUIP, ch, &tmp_char, &tmp_object);
if (tmp_object) {
if ((GET_OBJ_TYPE(tmp_object) == ITEM_DRINKCON) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_FOUNTAIN) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_CONTAINER)) {
send_to_char(ch, "When you look inside, you see:\r\n");
look_in_obj(ch, arg);
}
}
}
ACMD(do_gold)
{
if (GET_GOLD(ch) == 0)
send_to_char(ch, "You're broke!\r\n");
else if (GET_GOLD(ch) == 1)
send_to_char(ch, "You have one miserable little gold coin.\r\n");
else
send_to_char(ch, "You have %d gold coins.\r\n", GET_GOLD(ch));
}
ACMD(do_score)
{
struct time_info_data playing_time;
if (IS_NPC(ch))
return;
send_to_char(ch, "You are %d years old.", GET_AGE(ch));
if (age(ch)->month == 0 && age(ch)->day == 0)
send_to_char(ch, " It's your birthday today.\r\n");
else
send_to_char(ch, "\r\n");
send_to_char(ch, "You have %d(%d) hit, %d(%d) mana and %d(%d) movement points.\r\n",
GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch),
GET_MOVE(ch), GET_MAX_MOVE(ch));
send_to_char(ch, "Your armor class is %d/10, and your alignment is %d.\r\n",
compute_armor_class(ch), GET_ALIGNMENT(ch));
send_to_char(ch, "You have %d exp, %d gold coins, and %d questpoints.\r\n",
GET_EXP(ch), GET_GOLD(ch), GET_QUESTPOINTS(ch));
if (GET_LEVEL(ch) < LVL_IMMORT)
send_to_char(ch, "You need %d exp to reach your next level.\r\n",
level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - GET_EXP(ch));
playing_time = *real_time_passed((time(0) - ch->player.time.logon) +
ch->player.time.played, 0);
send_to_char(ch, "You have been playing for %d day%s and %d hour%s.\r\n",
playing_time.day, playing_time.day == 1 ? "" : "s",
playing_time.hours, playing_time.hours == 1 ? "" : "s");
send_to_char(ch, "This ranks you as %s %s (level %d).\r\n",
GET_NAME(ch), GET_TITLE(ch), GET_LEVEL(ch));
switch (GET_POS(ch)) {
case POS_DEAD:
send_to_char(ch, "You are DEAD!\r\n");
break;
case POS_MORTALLYW:
send_to_char(ch, "You are mortally wounded! You should seek help!\r\n");
break;
case POS_INCAP:
send_to_char(ch, "You are incapacitated, slowly fading away...\r\n");
break;
case POS_STUNNED:
send_to_char(ch, "You are stunned! You can't move!\r\n");
break;
case POS_SLEEPING:
send_to_char(ch, "You are sleeping.\r\n");
break;
case POS_RESTING:
send_to_char(ch, "You are resting.\r\n");
break;
case POS_SITTING:
if (!SITTING(ch))
send_to_char(ch, "You are sitting.\r\n");
else {
struct obj_data *furniture = SITTING(ch);
send_to_char(ch, "You are sitting upon %s.\r\n", furniture->short_description);
}
break;
case POS_FIGHTING:
send_to_char(ch, "You are fighting %s.\r\n", FIGHTING(ch) ? PERS(FIGHTING(ch), ch) : "thin air");
break;
case POS_STANDING:
send_to_char(ch, "You are standing.\r\n");
break;
default:
send_to_char(ch, "You are floating.\r\n");
break;
}
if (GET_COND(ch, DRUNK) > 10)
send_to_char(ch, "You are intoxicated.\r\n");
if (GET_COND(ch, HUNGER) == 0)
send_to_char(ch, "You are hungry.\r\n");
if (GET_COND(ch, THIRST) == 0)
send_to_char(ch, "You are thirsty.\r\n");
if (AFF_FLAGGED(ch, AFF_BLIND))
send_to_char(ch, "You have been blinded!\r\n");
if (AFF_FLAGGED(ch, AFF_INVISIBLE))
send_to_char(ch, "You are invisible.\r\n");
if (AFF_FLAGGED(ch, AFF_DETECT_INVIS))
send_to_char(ch, "You are sensitive to the presence of invisible things.\r\n");
if (AFF_FLAGGED(ch, AFF_SANCTUARY))
send_to_char(ch, "You are protected by Sanctuary.\r\n");
if (AFF_FLAGGED(ch, AFF_POISON))
send_to_char(ch, "You are poisoned!\r\n");
if (AFF_FLAGGED(ch, AFF_CHARM))
send_to_char(ch, "You have been charmed!\r\n");
if (affected_by_spell(ch, SPELL_ARMOR))
send_to_char(ch, "You feel protected.\r\n");
if (AFF_FLAGGED(ch, AFF_INFRAVISION))
send_to_char(ch, "Your eyes are glowing red.\r\n");
if (PRF_FLAGGED(ch, PRF_SUMMONABLE))
send_to_char(ch, "You are summonable by other players.\r\n");
if (GET_LEVEL(ch) >= LVL_IMMORT) {
if (POOFIN(ch))
send_to_char(ch, "%sPOOFIN: %s%s %s%s\r\n", QYEL, QCYN, GET_NAME(ch), POOFIN(ch), QNRM);
else
send_to_char(ch, "%sPOOFIN: %s%s appears with an ear-splitting bang.%s\r\n", QYEL, QCYN, GET_NAME(ch), QNRM);
if (POOFOUT(ch))
send_to_char(ch, "%sPOOFOUT: %s%s %s%s\r\n", QYEL, QCYN, GET_NAME(ch), POOFOUT(ch), QNRM);
else
send_to_char(ch, "%sPOOFOUT: %s%s disappears in a puff of smoke.%s\r\n", QYEL, QCYN, GET_NAME(ch), QNRM);
}
}
ACMD(do_inventory)
{
send_to_char(ch, "You are carrying:\r\n");
list_obj_to_char(ch->carrying, ch, SHOW_OBJ_SHORT, TRUE);
}
ACMD(do_equipment)
{
int i, found = 0;
send_to_char(ch, "You are using:\r\n");
for (i = 0; i < NUM_WEARS; i++) {
if (GET_EQ(ch, i)) {
if (CAN_SEE_OBJ(ch, GET_EQ(ch, i))) {
send_to_char(ch, "%s", wear_where[i]);
show_obj_to_char(GET_EQ(ch, i), ch, SHOW_OBJ_SHORT);
found = TRUE;
} else {
send_to_char(ch, "%s", wear_where[i]);
send_to_char(ch, "Something.\r\n");
found = TRUE;
}
}
}
if (!found)
send_to_char(ch, " Nothing.\r\n");
}
ACMD(do_time)
{
const char *suf;
int weekday, day;
/* day in [1..35] */
day = time_info.day + 1;
/* 35 days in a month, 7 days a week */
weekday = ((35 * time_info.month) + day) % 7;
send_to_char(ch, "It is %d o'clock %s, on %s.\r\n",
(time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12),
time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]);
/* Peter Ajamian supplied the following as a fix for a bug introduced in the
* ordinal display that caused 11, 12, and 13 to be incorrectly displayed as
* 11st, 12nd, and 13rd. Nate Winters had already submitted a fix, but it
* hard-coded a limit on ordinal display which I want to avoid. -dak */
suf = "th";
if (((day % 100) / 10) != 1) {
switch (day % 10) {
case 1:
suf = "st";
break;
case 2:
suf = "nd";
break;
case 3:
suf = "rd";
break;
}
}
send_to_char(ch, "The %d%s Day of the %s, Year %d.\r\n",
day, suf, month_name[time_info.month], time_info.year);
}
ACMD(do_weather)
{
const char *sky_look[] = {
"cloudless",
"cloudy",
"rainy",
"lit by flashes of lightning"
};
if (OUTSIDE(ch))
{
send_to_char(ch, "The sky is %s and %s.\r\n", sky_look[weather_info.sky],
weather_info.change >= 0 ? "you feel a warm wind from south" :
"your foot tells you bad weather is due");
if (GET_LEVEL(ch) >= LVL_GOD)
send_to_char(ch, "Pressure: %d (change: %d), Sky: %d (%s)\r\n",
weather_info.pressure,
weather_info.change,
weather_info.sky,
sky_look[weather_info.sky]);
}
else
send_to_char(ch, "You have no feeling about the weather at all.\r\n");
}
/* puts -'s instead of spaces */
void space_to_minus(char *str)
{
while ((str = strchr(str, ' ')) != NULL)
*str = '-';
}
int search_help(char *argument, int level)
{
int chk, bot, top, mid, minlen;
bot = 0;
top = top_of_h_table;
minlen = strlen(argument);
while (bot <= top) {
mid = (bot + top) / 2;
if (!(chk = strn_cmp(argument, help_table[mid].keywords, minlen))) {
while ((mid > 0) && !strn_cmp(argument, help_table[mid - 1].keywords, minlen))
mid--;
while (level < help_table[mid].min_level && mid < (bot + top) / 2)
mid++;
if (strn_cmp(argument, help_table[mid].keywords, minlen) || level < help_table[mid].min_level)
break;
return mid;
}
else if (chk > 0)
bot = mid + 1;
else
top = mid - 1;
}
return NOWHERE;
}
ACMD(do_help)
{
int mid = 0;
if (!ch->desc)
return;
skip_spaces(&argument);
if (!help_table) {
send_to_char(ch, "No help available.\r\n");
return;
}
if (!*argument) {
if (GET_LEVEL(ch) < LVL_IMMORT)
page_string(ch->desc, help, 0);
else
page_string(ch->desc, ihelp, 0);
return;
}
space_to_minus(argument);
if ((mid = search_help(argument, GET_LEVEL(ch))) == NOWHERE) {
send_to_char(ch, "There is no help on that word.\r\n");
mudlog(NRM, MAX(LVL_IMPL, GET_INVIS_LEV(ch)), TRUE,
"%s tried to get help on %s", GET_NAME(ch), argument);
int i, found = 0;
for (i = 0; i <= top_of_h_table; i++) {
if (help_table[i].min_level > GET_LEVEL(ch))
continue;
/* to help narrow down results, if they don't
start with the same letters, move on */
if (*argument != *help_table[i].keywords)
continue;
if (levenshtein_distance(argument, help_table[i].keywords) <= 2) {
if (!found) {
send_to_char(ch, "\r\nDid you mean:\r\n");
found = 1;
}
send_to_char(ch, " %s\r\n", help_table[i].keywords);
}
}
return;
}
page_string(ch->desc, help_table[mid].entry, 0);
}
#define WHO_FORMAT \
"Usage: who [minlev[-maxlev]] [-n name] [-c classlist] [-k] [-l] [-n] [-q] [-r] [-s] [-z]\r\n"
/* Written by Rhade */
ACMD(do_who)
{
struct descriptor_data *d;
struct char_data *tch;
int i, num_can_see = 0;
char name_search[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH];
char mode;
int low = 0, high = LVL_IMPL, localwho = 0, questwho = 0;
int showclass = 0, short_list = 0, outlaws = 0;
int who_room = 0, showgroup = 0, showleader = 0;
skip_spaces(&argument);
strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */
name_search[0] = '\0';
while (*buf) {
char arg[MAX_INPUT_LENGTH], buf1[MAX_INPUT_LENGTH];
half_chop(buf, arg, buf1);
if (isdigit(*arg)) {
sscanf(arg, "%d-%d", &low, &high);
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
} else if (*arg == '-') {
mode = *(arg + 1); /* just in case; we destroy arg in the switch */
switch (mode) {
case 'k':
outlaws = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'z':
localwho = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 's':
short_list = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'q':
questwho = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'n':
half_chop(buf1, name_search, buf);
break;
case 'r':
who_room = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'c':
half_chop(buf1, arg, buf);
showclass = find_class_bitvector(arg);
break;
case 'l':
showleader = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'g':
showgroup = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
default:
send_to_char(ch, "%s", WHO_FORMAT);
return;
}
} else {
send_to_char(ch, "%s", WHO_FORMAT);
return;
}
}
struct {
char *disp;
int min_level;
int max_level;
int count; /* must always start as 0 */
} rank[] = {
{ "Immortals\r\n---------\r\n", LVL_IMMORT, LVL_IMPL, 0},
{ "Mortals\r\n-------\r\n", 1, LVL_IMMORT - 1, 0 },
{ "\n", 0, 0, 0 }
};
for (d = descriptor_list; d && !short_list; d = d->next) {
if (d->original)
tch = d->original;
else if (!(tch = d->character))
continue;
if (CAN_SEE(ch, tch) && IS_PLAYING(d)) {
if (*name_search && str_cmp(GET_NAME(tch), name_search) &&
!strstr(GET_TITLE(tch), name_search))
continue;
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) && !PLR_FLAGGED(tch, PLR_THIEF))
continue;
if (questwho && !PRF_FLAGGED(tch, PRF_QUEST))
continue;
if (localwho && world[IN_ROOM(ch)].zone != world[IN_ROOM(tch)].zone)
continue;
if (who_room && (IN_ROOM(tch) != IN_ROOM(ch)))
continue;
if (showclass && !(showclass & (1 << GET_CLASS(tch))))
continue;
if (showgroup && (!tch->master || !AFF_FLAGGED(tch, AFF_GROUP)))
continue;
if (showleader && (!tch->followers || !AFF_FLAGGED(tch, AFF_GROUP)))
continue;
for (i = 0; *rank[i].disp != '\n'; i++)
if (GET_LEVEL(tch) >= rank[i].min_level && GET_LEVEL(tch) <= rank[i].max_level)
rank[i].count++;
}
}
for (i = 0; *rank[i].disp != '\n'; i++) {
if (!rank[i].count && !short_list)
continue;
if (short_list)
send_to_char(ch, "Players\r\n-------\r\n");
else
send_to_char(ch, rank[i].disp);
for (d = descriptor_list; d; d = d->next) {
if (d->original)
tch = d->original;
else if (!(tch = d->character))
continue;
if ((GET_LEVEL(tch) < rank[i].min_level || GET_LEVEL(tch) > rank[i].max_level) && !short_list)
continue;
if (!IS_PLAYING(d))
continue;
if (*name_search && str_cmp(GET_NAME(tch), name_search) &&
!strstr(GET_TITLE(tch), name_search))
continue;
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) && !PLR_FLAGGED(tch, PLR_THIEF))
continue;
if (questwho && !PRF_FLAGGED(tch, PRF_QUEST))
continue;
if (localwho && world[IN_ROOM(ch)].zone != world[IN_ROOM(tch)].zone)
continue;
if (who_room && (IN_ROOM(tch) != IN_ROOM(ch)))
continue;
if (showclass && !(showclass & (1 << GET_CLASS(tch))))
continue;
if (showgroup && (!tch->master || !AFF_FLAGGED(tch, AFF_GROUP)))
continue;
if (showleader && (!tch->followers || !AFF_FLAGGED(tch, AFF_GROUP)))
continue;
if (short_list) {
send_to_char(ch, "%s[%2d %s] %-12.12s%s%s",
(GET_LEVEL(tch) >= LVL_IMMORT ? CCYEL(ch, C_SPR) : ""),
GET_LEVEL(tch), CLASS_ABBR(tch), GET_NAME(tch),
CCNRM(ch, C_SPR), ((!(++num_can_see % 4)) ? "\r\n" : ""));
} else {
num_can_see++;
send_to_char(ch, "%s[%2d %s] %s%s%s%s",
(GET_LEVEL(tch) >= LVL_IMMORT ? CCYEL(ch, C_SPR) : ""),
GET_LEVEL(tch), CLASS_ABBR(tch),
GET_NAME(tch), (*GET_TITLE(tch) ? " " : ""), GET_TITLE(tch),
CCNRM(ch, C_SPR));
if (GET_INVIS_LEV(tch))
send_to_char(ch, " (i%d)", GET_INVIS_LEV(tch));
else if (AFF_FLAGGED(tch, AFF_INVISIBLE))
send_to_char(ch, " (invis)");
if (PLR_FLAGGED(tch, PLR_MAILING))
send_to_char(ch, " (mailing)");
else if (d->olc)
send_to_char(ch, " (OLC)");
else if (PLR_FLAGGED(tch, PLR_WRITING))
send_to_char(ch, " (writing)");
if (d->original)
send_to_char(ch, " (out of body)");
if (d->connected == CON_OEDIT)
send_to_char(ch, " (Object Edit)");
if (d->connected == CON_MEDIT)
send_to_char(ch, " (Mobile Edit)");
if (d->connected == CON_ZEDIT)
send_to_char(ch, " (Zone Edit)");
if (d->connected == CON_SEDIT)
send_to_char(ch, " (Shop Edit)");
if (d->connected == CON_REDIT)
send_to_char(ch, " (Room Edit)");
if (d->connected == CON_TEDIT)
send_to_char(ch, " (Text Edit)");
if (d->connected == CON_TRIGEDIT)
send_to_char(ch, " (Trigger Edit)");
if (d->connected == CON_AEDIT)
send_to_char(ch, " (Social Edit)");
if (d->connected == CON_CEDIT)
send_to_char(ch, " (Configuration Edit)");
if (d->connected == CON_HEDIT)
send_to_char(ch, " (Help edit)");
if (PRF_FLAGGED(tch, PRF_BUILDWALK))
send_to_char(ch, " (Buildwalking)");
if (PRF_FLAGGED(tch, PRF_AFK))
send_to_char(ch, " (AFK)");
if (PRF_FLAGGED(ch, PRF_NOGOSS))
send_to_char(ch, " (nogos)");
if (PRF_FLAGGED(ch, PRF_NOWIZ))
send_to_char(ch, " (nowiz)");
if (PRF_FLAGGED(tch, PRF_NOSHOUT))
send_to_char(ch, " (noshout)");
if (PRF_FLAGGED(tch, PRF_NOTELL))
send_to_char(ch, " (notell)");
if (PRF_FLAGGED(tch, PRF_QUEST))
send_to_char(ch, " (quest)");
if (PLR_FLAGGED(tch, PLR_THIEF))
send_to_char(ch, " (THIEF)");
if (PLR_FLAGGED(tch, PLR_KILLER))
send_to_char(ch, " (KILLER)");
send_to_char(ch, "\r\n");
}
}
send_to_char(ch, "\r\n");
if (short_list)
break;
}
if (short_list && num_can_see % 4)
send_to_char(ch, "\r\n");
if (!num_can_see)
send_to_char(ch, "Nobody at all!\r\n");
else if (num_can_see == 1)
send_to_char(ch, "One lonely character displayed.\r\n");
else
send_to_char(ch, "%d characters displayed.\r\n", num_can_see);
}
#define USERS_FORMAT \
"format: users [-l minlevel[-maxlevel]] [-n name] [-h host] [-c classlist] [-o] [-p]\r\n"
ACMD(do_users)
{
char line[200], line2[220], idletime[10], classname[20];
char state[30], *timeptr, mode;
char name_search[MAX_INPUT_LENGTH], host_search[MAX_INPUT_LENGTH];
struct char_data *tch;
struct descriptor_data *d;
int low = 0, high = LVL_IMPL, num_can_see = 0;
int showclass = 0, outlaws = 0, playing = 0, deadweight = 0;
char buf[MAX_INPUT_LENGTH], arg[MAX_INPUT_LENGTH];
host_search[0] = name_search[0] = '\0';
strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */
while (*buf) {
char buf1[MAX_INPUT_LENGTH];
half_chop(buf, arg, buf1);
if (*arg == '-') {
mode = *(arg + 1); /* just in case; we destroy arg in the switch */
switch (mode) {
case 'o':
case 'k':
outlaws = 1;
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'p':
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'd':
deadweight = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'l':
playing = 1;
half_chop(buf1, arg, buf);
sscanf(arg, "%d-%d", &low, &high);
break;
case 'n':
playing = 1;
half_chop(buf1, name_search, buf);
break;
case 'h':
playing = 1;
half_chop(buf1, host_search, buf);
break;
case 'c':
playing = 1;
half_chop(buf1, arg, buf);
showclass = find_class_bitvector(arg);
break;
default:
send_to_char(ch, "%s", USERS_FORMAT);
return;
} /* end of switch */
} else { /* endif */
send_to_char(ch, "%s", USERS_FORMAT);
return;
}
} /* end while (parser) */
send_to_char(ch,
"Num Class Name State Idl Login@@ Site\r\n"
"--- ------- ------------ -------------- ----- -------- ------------------------\r\n");
one_argument(argument, arg);
for (d = descriptor_list; d; d = d->next) {
if (STATE(d) != CON_PLAYING && playing)
continue;
if (STATE(d) == CON_PLAYING && deadweight)
continue;
if (IS_PLAYING(d)) {
if (d->original)
tch = d->original;
else if (!(tch = d->character))
continue;
if (*host_search && !strstr(d->host, host_search))
continue;
if (*name_search && str_cmp(GET_NAME(tch), name_search))
continue;
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) &&
!PLR_FLAGGED(tch, PLR_THIEF))
continue;
if (showclass && !(showclass & (1 << GET_CLASS(tch))))
continue;
if (GET_INVIS_LEV(ch) > GET_LEVEL(ch))
continue;
if (d->original)
sprintf(classname, "[%2d %s]", GET_LEVEL(d->original),
CLASS_ABBR(d->original));
else
sprintf(classname, "[%2d %s]", GET_LEVEL(d->character),
CLASS_ABBR(d->character));
} else
strcpy(classname, " - ");
timeptr = asctime(localtime(&d->login_time));
timeptr += 11;
*(timeptr + 8) = '\0';
if (STATE(d) == CON_PLAYING && d->original)
strcpy(state, "Switched");
else
strcpy(state, connected_types[STATE(d)]);
if (d->character && STATE(d) == CON_PLAYING)
sprintf(idletime, "%5d", d->character->char_specials.timer *
SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN);
else
strcpy(idletime, " ");
sprintf(line, "%3d %-7s %-12s %-14s %-3s %-8s ", d->desc_num, classname,
d->original && d->original->player.name ? d->original->player.name :
d->character && d->character->player.name ? d->character->player.name :
"UNDEFINED",
state, idletime, timeptr);
if (d->host && *d->host)
sprintf(line + strlen(line), "[%s]\r\n", d->host);
else
strcat(line, "[Hostname unknown]\r\n");
if (STATE(d) != CON_PLAYING) {
sprintf(line2, "%s%s%s", CCGRN(ch, C_SPR), line, CCNRM(ch, C_SPR));
strcpy(line, line2);
}
if (STATE(d) != CON_PLAYING ||
(STATE(d) == CON_PLAYING && CAN_SEE(ch, d->character))) {
send_to_char(ch, "%s", line);
num_can_see++;
}
}
send_to_char(ch, "\r\n%d visible sockets connected.\r\n", num_can_see);
}
/* Generic page_string function for displaying text */
ACMD(do_gen_ps)
{
switch (subcmd) {
case SCMD_CREDITS:
page_string(ch->desc, credits, 0);
break;
case SCMD_NEWS:
page_string(ch->desc, news, 0);
break;
case SCMD_INFO:
page_string(ch->desc, info, 0);
break;
case SCMD_WIZLIST:
page_string(ch->desc, wizlist, 0);
break;
case SCMD_IMMLIST:
page_string(ch->desc, immlist, 0);
break;
case SCMD_HANDBOOK:
page_string(ch->desc, handbook, 0);
break;
case SCMD_POLICIES:
page_string(ch->desc, policies, 0);
break;
case SCMD_MOTD:
page_string(ch->desc, motd, 0);
break;
case SCMD_IMOTD:
page_string(ch->desc, imotd, 0);
break;
case SCMD_CLEAR:
send_to_char(ch, "\033[H\033[J");
break;
case SCMD_VERSION:
send_to_char(ch, "%s\r\n", tbamud_version);
send_to_char(ch, "%s\r\n", oasisolc_version);
send_to_char(ch, "%s\r\n", DG_SCRIPT_VERSION);
send_to_char(ch, "%s\r\n", ascii_pfiles_version);
break;
case SCMD_WHOAMI:
send_to_char(ch, "%s\r\n", GET_NAME(ch));
break;
default:
log("SYSERR: Unhandled case in do_gen_ps. (%d)", subcmd);
/* SYSERR_DESC: General page string function for such things as 'credits',
* 'news', 'wizlist', 'clear', 'version'. This occurs when a call is made
* to this routine that is not one of the predefined calls. To correct it,
* either a case needs to be added into the function to account for the
* subcmd that is being passed to it, or the call to the function needs to
* have the correct subcmd put into place. */
return;
}
}
void perform_mortal_where(struct char_data *ch, char *arg)
{
struct char_data *i;
struct descriptor_data *d;
if (!*arg) {
send_to_char(ch, "Players in your Zone\r\n--------------------\r\n");
for (d = descriptor_list; d; d = d->next) {
if (STATE(d) != CON_PLAYING || d->character == ch)
continue;
if ((i = (d->original ? d->original : d->character)) == NULL)
continue;
if (IN_ROOM(i) == NOWHERE || !CAN_SEE(ch, i))
continue;
if (world[IN_ROOM(ch)].zone != world[IN_ROOM(i)].zone)
continue;
send_to_char(ch, "%-20s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM);
}
} else { /* print only FIRST char, not all. */
for (i = character_list; i; i = i->next) {
if (IN_ROOM(i) == NOWHERE || i == ch)
continue;
if (!CAN_SEE(ch, i) || world[IN_ROOM(i)].zone != world[IN_ROOM(ch)].zone)
continue;
if (!isname(arg, i->player.name))
continue;
send_to_char(ch, "%-25s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM);
return;
}
send_to_char(ch, "Nobody around by that name.\r\n");
}
}
void print_object_location(int num, struct obj_data *obj, struct char_data *ch,
int recur)
{
if (num > 0)
send_to_char(ch, "O%3d. %-25s%s - ", num, obj->short_description, QNRM);
else
send_to_char(ch, "%33s", " - ");
if (obj->proto_script)
send_to_char(ch, "[TRIG]");
if (IN_ROOM(obj) != NOWHERE)
send_to_char(ch, "[%5d] %s%s\r\n", GET_ROOM_VNUM(IN_ROOM(obj)), world[IN_ROOM(obj)].name, QNRM);
else if (obj->carried_by)
send_to_char(ch, "carried by %s%s\r\n", PERS(obj->carried_by, ch), QNRM);
else if (obj->worn_by)
send_to_char(ch, "worn by %s%s\r\n", PERS(obj->worn_by, ch), QNRM);
else if (obj->in_obj) {
send_to_char(ch, "inside %s%s%s\r\n", obj->in_obj->short_description, QNRM, (recur ? ", which is" : " "));
if (recur)
print_object_location(0, obj->in_obj, ch, recur);
} else
send_to_char(ch, "in an unknown location\r\n");
}
void perform_immort_where(struct char_data *ch, char *arg)
{
struct char_data *i;
struct obj_data *k;
struct descriptor_data *d;
int num = 0, found = 0;
if (!*arg) {
send_to_char(ch, "Players\r\n-------\r\n");
for (d = descriptor_list; d; d = d->next)
if (IS_PLAYING(d)) {
i = (d->original ? d->original : d->character);
if (i && CAN_SEE(ch, i) && (IN_ROOM(i) != NOWHERE)) {
if (d->original)
send_to_char(ch, "%-20s%s - [%5d] %s%s (in %s%s)\r\n",
GET_NAME(i), QNRM, GET_ROOM_VNUM(IN_ROOM(d->character)),
world[IN_ROOM(d->character)].name, QNRM, GET_NAME(d->character), QNRM);
else
send_to_char(ch, "%-20s%s - [%5d] %s%s\r\n", GET_NAME(i), QNRM, GET_ROOM_VNUM(IN_ROOM(i)), world[IN_ROOM(i)].name, QNRM);
}
}
} else {
for (i = character_list; i; i = i->next)
if (CAN_SEE(ch, i) && IN_ROOM(i) != NOWHERE && isname(arg, i->player.name)) {
found = 1;
send_to_char(ch, "M%3d. %-25s%s - [%5d] %-25s%s %s\r\n", ++num, GET_NAME(i), QNRM,
GET_ROOM_VNUM(IN_ROOM(i)), world[IN_ROOM(i)].name, QNRM,
(IS_NPC(i) && i->proto_script) ? "[TRIG]" : "");
}
for (num = 0, k = object_list; k; k = k->next)
if (CAN_SEE_OBJ(ch, k) && isname(arg, k->name)) {
found = 1;
print_object_location(++num, k, ch, TRUE);
}
if (!found)
send_to_char(ch, "Couldn't find any such thing.\r\n");
}
}
ACMD(do_where)
{
char arg[MAX_INPUT_LENGTH];
one_argument(argument, arg);
if (GET_LEVEL(ch) >= LVL_IMMORT)
perform_immort_where(ch, arg);
else
perform_mortal_where(ch, arg);
}
ACMD(do_levels)
{
char buf[MAX_STRING_LENGTH];
size_t i, len = 0, nlen;
if (IS_NPC(ch)) {
send_to_char(ch, "You ain't nothin' but a hound-dog.\r\n");
return;
}
for (i = 1; i < LVL_IMMORT; i++) {
nlen = snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d-%-8d : ", i,
level_exp(GET_CLASS(ch), i), level_exp(GET_CLASS(ch), i + 1) - 1);
if (len + nlen >= sizeof(buf) || nlen < 0)
break;
len += nlen;
switch (GET_SEX(ch)) {
case SEX_MALE:
case SEX_NEUTRAL:
nlen = snprintf(buf + len, sizeof(buf) - len, "%s\r\n", title_male(GET_CLASS(ch), i));
break;
case SEX_FEMALE:
nlen = snprintf(buf + len, sizeof(buf) - len, "%s\r\n", title_female(GET_CLASS(ch), i));
break;
default:
nlen = snprintf(buf + len, sizeof(buf) - len, "Oh dear. You seem to be sexless.\r\n");
break;
}
if (len + nlen >= sizeof(buf) || nlen < 0)
break;
len += nlen;
}
if (len < sizeof(buf))
snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d : Immortality\r\n",
LVL_IMMORT, level_exp(GET_CLASS(ch), LVL_IMMORT));
page_string(ch->desc, buf, TRUE);
}
ACMD(do_consider)
{
char buf[MAX_INPUT_LENGTH];
struct char_data *victim;
int diff;
one_argument(argument, buf);
if (!(victim = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM))) {
send_to_char(ch, "Consider killing who?\r\n");
return;
}
if (victim == ch) {
send_to_char(ch, "Easy! Very easy indeed!\r\n");
return;
}
if (!IS_NPC(victim)) {
send_to_char(ch, "Would you like to borrow a cross and a shovel?\r\n");
return;
}
diff = (GET_LEVEL(victim) - GET_LEVEL(ch));
if (diff <= -10)
send_to_char(ch, "Now where did that chicken go?\r\n");
else if (diff <= -5)
send_to_char(ch, "You could do it with a needle!\r\n");
else if (diff <= -2)
send_to_char(ch, "Easy.\r\n");
else if (diff <= -1)
send_to_char(ch, "Fairly easy.\r\n");
else if (diff == 0)
send_to_char(ch, "The perfect match!\r\n");
else if (diff <= 1)
send_to_char(ch, "You would need some luck!\r\n");
else if (diff <= 2)
send_to_char(ch, "You would need a lot of luck!\r\n");
else if (diff <= 3)
send_to_char(ch, "You would need a lot of luck and great equipment!\r\n");
else if (diff <= 5)
send_to_char(ch, "Do you feel lucky, punk?\r\n");
else if (diff <= 10)
send_to_char(ch, "Are you mad!?\r\n");
else if (diff <= 100)
send_to_char(ch, "You ARE mad!\r\n");
}
ACMD(do_diagnose)
{
char buf[MAX_INPUT_LENGTH];
struct char_data *vict;
one_argument(argument, buf);
if (*buf) {
if (!(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM)))
send_to_char(ch, "%s", CONFIG_NOPERSON);
else
diag_char_to_char(vict, ch);
} else {
if (FIGHTING(ch))
diag_char_to_char(FIGHTING(ch), ch);
else
send_to_char(ch, "Diagnose who?\r\n");
}
}
ACMD(do_toggle)
{
char buf2[4], arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
int toggle, tp, wimp_lev, result = 0, len = 0;
const char *types[] = { "off", "brief", "normal", "on", "\n" };
if (IS_NPC(ch))
return;
argument = one_argument(argument, arg);
any_one_arg(argument, arg2); /* so that we don't skip 'on' */
if (!*arg) {
if (!GET_WIMP_LEV(ch))
strcpy(buf2, "OFF"); /* strcpy: OK */
else
sprintf(buf2, "%-3.3d", GET_WIMP_LEV(ch)); /* sprintf: OK */
if (GET_LEVEL(ch) == LVL_IMPL) {
send_to_char(ch,
" SlowNameserver: %-3s "
" "
" Trackthru Doors: %-3s\r\n",
ONOFF(CONFIG_NS_IS_SLOW),
ONOFF(CONFIG_TRACK_T_DOORS));
}
if (GET_LEVEL(ch) >= LVL_IMMORT) {
send_to_char(ch,
" Buildwalk: %-3s "
" NoWiz: %-3s "
" ClsOLC: %-3s\r\n"
" NoHassle: %-3s "
" Holylight: %-3s "
" ShowVnums: %-3s\r\n"
" Syslog: %-3s\r\n",
ONOFF(PRF_FLAGGED(ch, PRF_BUILDWALK)),
ONOFF(PRF_FLAGGED(ch, PRF_NOWIZ)),
ONOFF(PRF_FLAGGED(ch, PRF_CLS)),
ONOFF(PRF_FLAGGED(ch, PRF_NOHASSLE)),
ONOFF(PRF_FLAGGED(ch, PRF_HOLYLIGHT)),
ONOFF(PRF_FLAGGED(ch, PRF_SHOWVNUMS)),
types[(PRF_FLAGGED(ch, PRF_LOG1) ? 1 : 0) + (PRF_FLAGGED(ch, PRF_LOG2) ? 2 : 0)]);
}
send_to_char(ch,
"Hit Pnt Display: %-3s "
" Brief: %-3s "
" Summonable: %-3s\r\n"
" Move Display: %-3s "
" Compact: %-3s "
" Quest: %-3s\r\n"
" Mana Display: %-3s "
" NoTell: %-3s "
" NoRepeat: %-3s\r\n"
" AutoExits: %-3s "
" NoShout: %-3s "
" Wimpy: %-3s\r\n"
" NoGossip: %-3s "
" NoAuction: %-3s "
" NoGrats: %-3s\r\n"
" AutoLoot: %-3s "
" AutoGold: %-3s "
" AutoSplit: %-3s\r\n"
" AutoSac: %-3s "
" AutoAssist: %-3s "
" AFK: %-3s\r\n"
" Pagelength: %-3d "
" Color: %s \r\n ",
ONOFF(PRF_FLAGGED(ch, PRF_DISPHP)),
ONOFF(PRF_FLAGGED(ch, PRF_BRIEF)),
ONOFF(PRF_FLAGGED(ch, PRF_SUMMONABLE)),
ONOFF(PRF_FLAGGED(ch, PRF_DISPMOVE)),
ONOFF(PRF_FLAGGED(ch, PRF_COMPACT)),
ONOFF(PRF_FLAGGED(ch, PRF_QUEST)),
ONOFF(PRF_FLAGGED(ch, PRF_DISPMANA)),
ONOFF(PRF_FLAGGED(ch, PRF_NOTELL)),
ONOFF(PRF_FLAGGED(ch, PRF_NOREPEAT)),
ONOFF(PRF_FLAGGED(ch, PRF_AUTOEXIT)),
ONOFF(PRF_FLAGGED(ch, PRF_NOSHOUT)),
buf2,
ONOFF(PRF_FLAGGED(ch, PRF_NOGOSS)),
ONOFF(PRF_FLAGGED(ch, PRF_NOAUCT)),
ONOFF(PRF_FLAGGED(ch, PRF_NOGRATZ)),
ONOFF(PRF_FLAGGED(ch, PRF_AUTOLOOT)),
ONOFF(PRF_FLAGGED(ch, PRF_AUTOGOLD)),
ONOFF(PRF_FLAGGED(ch, PRF_AUTOSPLIT)),
ONOFF(PRF_FLAGGED(ch, PRF_AUTOSAC)),
ONOFF(PRF_FLAGGED(ch, PRF_AUTOASSIST)),
ONOFF(PRF_FLAGGED(ch, PRF_AFK)),
GET_PAGE_LENGTH(ch),
types[COLOR_LEV(ch)]);
return;
}
const struct {
char *command;
bitvector_t toggle; /* this needs changing once hashmaps are implemented */
char min_level;
char *disable_msg;
char *enable_msg;
} tog_messages[] = {
{"summonable", PRF_SUMMONABLE, 0,
"You are now safe from summoning by other players.\r\n",
"You may now be summoned by other players.\r\n"},
{"nohassle", PRF_NOHASSLE, LVL_IMMORT,
"Nohassle disabled.\r\n",
"Nohassle enabled.\r\n"},
{"brief", PRF_BRIEF, 0,
"Brief mode off.\r\n",
"Brief mode on.\r\n"},
{"compact", PRF_COMPACT, 0,
"Compact mode off.\r\n",
"Compact mode on.\r\n"},
{"notell", PRF_NOTELL, 0,
"You can now hear tells.\r\n",
"You are now deaf to tells.\r\n"},
{"noauction", PRF_NOAUCT, 0,
"You can now hear auctions.\r\n",
"You are now deaf to auctions.\r\n"},
{"noshout", PRF_NOSHOUT, 0,
"You can now hear shouts.\r\n",
"You are now deaf to shouts.\r\n"},
{"nogossip", PRF_NOGOSS, 0,
"You can now hear gossip.\r\n",
"You are now deaf to gossip.\r\n"},
{"nograts", PRF_NOGRATZ, 0,
"You can now hear gratz.\r\n",
"You are now deaf to gratz.\r\n"},
{"nowiz", PRF_NOWIZ, LVL_IMMORT,
"You can now hear the Wiz-channel.\r\n",
"You are now deaf to the Wiz-channel.\r\n"},
{"quest", PRF_QUEST, 0,
"Okay, you are part of the Quest.\r\n",
"You are no longer part of the Quest.\r\n"},
{"showvnums", PRF_SHOWVNUMS, LVL_IMMORT,
"You will no longer see the vnums.\r\n",
"You will now see the vnums.\r\n"},
{"norepeat", PRF_NOREPEAT, 0,
"You will now have your communication repeated.\r\n",
"You will no longer have your communication repeated.\r\n"},
{"holylight", PRF_HOLYLIGHT, LVL_IMMORT,
"HolyLight mode off.\r\n",
"HolyLight mode on.\r\n"},
{"slownameserver", 0, LVL_IMPL,
"Nameserver_is_slow changed to OFF; IP addresses will now be resolved.\r\n",
"Nameserver_is_slow changed to ON; sitenames will no longer be resolved.\r\n"},
{"autoexits", PRF_AUTOEXIT, 0,
"Autoexits disabled.\r\n",
"Autoexits enabled.\r\n"},
{"trackthru", 0, LVL_IMPL,
"Players can no longer track through doors.\r\n",
"Players can now track through doors.\r\n"},
{"clsolc", PRF_CLS, LVL_BUILDER,
"You will no longer clear screen in OLC.\r\n",
"You will now clear screen in OLC.\r\n"},
{"buildwalk", PRF_BUILDWALK, LVL_BUILDER,
"Buildwalk is now Off.\r\n",
"Buildwalk is now On.\r\n"},
{"afk", PRF_AFK, 0,
"AFK is now Off.\r\n",
"AFK is now On.\r\n"},
{"color", 0, 0, "\n", "\n"},
{"syslog", 0, LVL_IMMORT, "\n", "\n"},
{"wimpy", 0, 0, "\n", "\n"},
{"pagelength", 0, 0, "\n", "\n"},
{"autoloot", PRF_AUTOLOOT, 0,
"Autoloot disabled.\r\n",
"Autoloot enabled.\r\n"},
{"autogold", PRF_AUTOGOLD, 0,
"Autogold disabled.\r\n",
"Autogold enabled.\r\n"},
{"autosplit", PRF_AUTOSPLIT, 0,
"Autosplit disabled.\r\n",
"Autosplit enabled.\r\n"},
{"autosac", PRF_AUTOSAC, 0,
"Autosac disabled.\r\n",
"Autosac enabled.\r\n"},
{"autoassist", PRF_AUTOASSIST, 0,
"Autoassist disabled.\r\n",
"Autoassist enabled.\r\n"},
{"\n", 0, -1, "\n", "\n"} /* must be last */
};
len = strlen(arg);
for (toggle = 0; *tog_messages[toggle].command != '\n'; toggle++)
if (!strncmp(arg, tog_messages[toggle].command, len))
break;
if (*tog_messages[toggle].command == '\n' || tog_messages[toggle].min_level > GET_LEVEL(ch)) {
send_to_char(ch, "You can't toggle that!\r\n");
return;
}
switch (toggle) {
case SCMD_COLOR:
if (!*arg2) {
send_to_char(ch, "Your current color level is %s.\r\n", types[COLOR_LEV(ch)]);
return;
}
if (((tp = search_block(arg2, types, FALSE)) == -1)) {
send_to_char(ch, "Usage: toggle color { Off | Normal | On }\r\n");
return;
}
REMOVE_BIT(PRF_FLAGS(ch), PRF_COLOR_1 | PRF_COLOR_2);
SET_BIT(PRF_FLAGS(ch), (PRF_COLOR_1 * (tp & 1)) | (PRF_COLOR_2 * (tp & 2) >> 1));
send_to_char(ch, "Your %scolor%s is now %s.\r\n", CCRED(ch, C_SPR), CCNRM(ch, C_OFF), types[tp]);
return;
case SCMD_SYSLOG:
if (!*arg2) {
send_to_char(ch, "Your syslog is currently %s.\r\n",
types[(PRF_FLAGGED(ch, PRF_LOG1) ? 1 : 0) + (PRF_FLAGGED(ch, PRF_LOG2) ? 2 : 0)]);
return;
}
if (((tp = search_block(arg2, types, FALSE)) == -1)) {
send_to_char(ch, "Usage: toggle syslog { Off | Brief | Normal | On }\r\n");
return;
}
REMOVE_BIT(PRF_FLAGS(ch), PRF_LOG1 | PRF_LOG2);
SET_BIT(PRF_FLAGS(ch), (PRF_LOG1 * (tp & 1)) | (PRF_LOG2 * (tp & 2) >> 1));
send_to_char(ch, "Your syslog is now %s.\r\n", types[tp]);
return;
case SCMD_SLOWNS:
result = (CONFIG_NS_IS_SLOW = !CONFIG_NS_IS_SLOW);
break;
case SCMD_TRACK:
result = (CONFIG_TRACK_T_DOORS = !CONFIG_TRACK_T_DOORS);
break;
case SCMD_BUILDWALK:
if (GET_LEVEL(ch) < LVL_BUILDER) {
send_to_char(ch, "Builders only, sorry.\r\n");
return;
}
result = PRF_TOG_CHK(ch, PRF_BUILDWALK);
if (PRF_FLAGGED(ch, PRF_BUILDWALK))
mudlog(CMP, GET_LEVEL(ch), TRUE,
"OLC: %s turned buildwalk on. Allowed zone %d", GET_NAME(ch), GET_OLC_ZONE(ch));
else
mudlog(CMP, GET_LEVEL(ch), TRUE,
"OLC: %s turned buildwalk off. Allowed zone %d", GET_NAME(ch), GET_OLC_ZONE(ch));
break;
case SCMD_AFK:
if ((result = PRF_TOG_CHK(ch, PRF_AFK)))
act("$n is now away from $s keyboard.", TRUE, ch, 0, 0, TO_ROOM);
else {
act("$n has returned to $s keyboard.", TRUE, ch, 0, 0, TO_ROOM);
if (has_mail(GET_IDNUM(ch)))
send_to_char(ch, "You have mail waiting.\r\n");
}
break;
case SCMD_WIMPY:
if (!*arg2) {
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(*arg2)) {
if ((wimp_lev = atoi(arg2)) != 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");
break;
case SCMD_PAGELENGTH:
if (!*arg2)
send_to_char(ch, "You current page length is set to %d lines.\r\n", GET_PAGE_LENGTH(ch));
else if (is_number(arg2)) {
GET_PAGE_LENGTH(ch) = MIN(MAX(atoi(arg2), 5), 255);
send_to_char(ch, "Okay, your page length is now set to %d lines.\r\n", GET_PAGE_LENGTH(ch));
} else
send_to_char(ch, "Please specify a number of lines (5 - 255).\r\n");
break;
default:
if (!*arg2) {
TOGGLE_BIT(PRF_FLAGS(ch), tog_messages[toggle].toggle);
result = (PRF_FLAGGED(ch, tog_messages[toggle].toggle));
} else if (!strcmp(arg2, "on")) {
SET_BIT(PRF_FLAGS(ch), tog_messages[toggle].toggle);
result = 1;
} else if (!strcmp(arg2, "off")) {
REMOVE_BIT(PRF_FLAGS(ch), tog_messages[toggle].toggle);
} else {
send_to_char(ch, "Value for %s must either be 'on' or 'off'.\r\n", tog_messages[toggle].command);
return;
}
}
if (result)
send_to_char(ch, "%s", tog_messages[toggle].enable_msg);
else
send_to_char(ch, "%s", tog_messages[toggle].disable_msg);
}
int sort_commands_helper(const void *a, const void *b)
{
return strcmp(complete_cmd_info[*(const int *)a].sort_as,
complete_cmd_info[*(const int *)b].sort_as);
}
void sort_commands(void)
{
int a, num_of_cmds = 0;
while (complete_cmd_info[num_of_cmds].command[0] != '\n')
num_of_cmds++;
num_of_cmds++; /* \n */
CREATE(cmd_sort_info, int, num_of_cmds);
for (a = 0; a < num_of_cmds; a++)
cmd_sort_info[a] = a;
/* Don't sort the RESERVED or \n entries. */
qsort(cmd_sort_info + 1, num_of_cmds - 2, sizeof(int), sort_commands_helper);
}
ACMD(do_commands)
{
int no, i, cmd_num;
int wizhelp = 0, socials = 0;
struct char_data *vict;
char arg[MAX_INPUT_LENGTH];
one_argument(argument, arg);
if (*arg) {
if (!(vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)) || IS_NPC(vict)) {
send_to_char(ch, "Who is that?\r\n");
return;
}
} else
vict = ch;
if (subcmd == SCMD_SOCIALS)
socials = 1;
else if (subcmd == SCMD_WIZHELP)
wizhelp = 1;
send_to_char(ch, "The following %s%s are available to %s:\r\n",
wizhelp ? "privileged " : "",
socials ? "socials" : "commands",
vict == ch ? "you" : GET_NAME(vict));
/* cmd_num starts at 1, not 0, to remove 'RESERVED' */
for (no = 1, cmd_num = 1; complete_cmd_info[cmd_sort_info[cmd_num]].command[0] != '\n'; cmd_num++) {
i = cmd_sort_info[cmd_num];
if (complete_cmd_info[i].minimum_level < 0 || GET_LEVEL(vict) < complete_cmd_info[i].minimum_level)
continue;
if ((complete_cmd_info[i].minimum_level >= LVL_IMMORT) != wizhelp)
continue;
if (!wizhelp && socials != (complete_cmd_info[i].command_pointer == do_action))
continue;
if (wizhelp && complete_cmd_info[i].command_pointer == do_action)
continue;
send_to_char(ch, "%-11s%s", complete_cmd_info[i].command, no++ % 7 == 0 ? "\r\n" : "");
}
if (no % 7 != 1)
send_to_char(ch, "\r\n");
}
void free_history(struct char_data *ch, int type)
{
struct txt_block *tmp = GET_HISTORY(ch, type), *ftmp;
while ((ftmp = tmp)) {
tmp = tmp->next;
if (ftmp->text)
free(ftmp->text);
free(ftmp);
}
GET_HISTORY(ch, type) = NULL;
}
ACMD(do_history)
{
char arg[MAX_INPUT_LENGTH];
one_argument(argument, arg);
int type = search_block(arg, history_types, FALSE);
if (!*arg || type < 0) {
int i;
send_to_char(ch, "Usage: history <");
for (i = 0; *history_types[i] != '\n'; i++) {
send_to_char(ch, " %s ", history_types[i]);
if (*history_types[i + 1] == '\n')
send_to_char(ch, ">\r\n");
else
send_to_char(ch, "|");
}
return;
}
if (GET_HISTORY(ch, type) && GET_HISTORY(ch, type)->text && *GET_HISTORY(ch, type)->text) {
struct txt_block *tmp;
for (tmp = GET_HISTORY(ch, type); tmp; tmp = tmp->next)
send_to_char(ch, "%s", tmp->text);
/* Make this a 1 if you want history to clear after viewing */
#if 0
free_history(ch, type);
#endif
} else
send_to_char(ch, "You have no history in that channel.\r\n");
}
#define HIST_LENGTH 100
void add_history(struct char_data *ch, char *str, int type)
{
int i = 0;
char time_str[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH];
if (IS_NPC(ch))
return;
struct txt_block *tmp = GET_HISTORY(ch, type);
time_t ct = time(0);
strftime(time_str, sizeof(time_str), "%H:%M ", localtime(&ct));
sprintf(buf, "%s%s", time_str, str);
if (!tmp) {
CREATE(GET_HISTORY(ch, type), struct txt_block, 1);
GET_HISTORY(ch, type)->text = strdup(buf);
}
else {
while (tmp->next)
tmp = tmp->next;
CREATE(tmp->next, struct txt_block, 1);
tmp->next->text = strdup(buf);
for (tmp = GET_HISTORY(ch, type); tmp; tmp = tmp->next, i++);
for (; i > HIST_LENGTH && GET_HISTORY(ch, type); i--) {
tmp = GET_HISTORY(ch, type);
GET_HISTORY(ch, type) = tmp->next;
if (tmp->text)
free(tmp->text);
free(tmp);
}
}
/* add this history message to ALL */
if (type != HIST_ALL)
add_history(ch, str, HIST_ALL);
}