/* ************************************************************************ * File: act.informative.c EmpireMUD AD 1.0 * * Usage: Player-level commands of an informative nature * * * * All rights reserved. See license.doc for complete information. * * * * Code base by Paul Clarke. EmpireMUD Project, a tbgMUD Production. * * Based upon CircleMUD 3.0, beta patch level 17, by Jeremy Elson. * * * * 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 "utils.h" #include "empire.h" #include "skills.h" /* extern variables */ extern const char *where[]; extern const char *sector_name[]; extern const char *dirs[]; extern const char *month_name[]; extern struct tribe_data tribe[]; extern const char *auspice[]; extern const char *breed[]; /* Outputs Attributes in a White Wolf manner, ex. Strength: **** */ void display_attributes(Creature ch, Creature to, bool real) { sbyte att[9]; int i, j; const char *att_types[] = { "Strength", "Charisma", "Perception", "Dexterity", "Manipulation", "Intelligence", "Stamina", "Appearance", "Wits" }; if (real) { att[0] = ch->real_abils.strength; att[1] = ch->real_abils.charisma; att[2] = ch->real_abils.perception; att[3] = ch->real_abils.dexterity; att[4] = ch->real_abils.manipulation; att[5] = ch->real_abils.intelligence; att[6] = ch->real_abils.stamina; att[7] = ch->real_abils.appearance; att[8] = ch->real_abils.wits; } else { att[0] = ch->aff_abils.strength; att[1] = ch->aff_abils.charisma; att[2] = ch->aff_abils.perception; att[3] = ch->aff_abils.dexterity; att[4] = ch->aff_abils.manipulation; att[5] = ch->aff_abils.intelligence; att[6] = ch->aff_abils.stamina; att[7] = ch->aff_abils.appearance; att[8] = ch->aff_abils.wits; } /* The header */ msg_to_char(to, " Physical Social Mental\r\n "); for (i = 0; i < 9; i++) { sprintf(buf, " %-14.14s", att_types[i]); for (j = 1; j <= 10; j++) { if (att[i] >= j) strcat(buf, "*"); else strcat(buf, " "); } /* Terminate at three columns */ if (!((i + 1) % 3)) strcat(buf, "\r\n "); msg_to_char(to, buf); } } /* Outputs Abilities in a White Wolf manner */ void display_abilities(Creature ch, Creature to) { extern const char *talents[]; extern const char *skills[]; extern const char *knowledges[]; int i, j; /* Header */ msg_to_char(to, " Talents Skills Knowledges\r\n "); for (i = 0; i < NUM_ABILITIES; i++) { *buf = '\0'; sprintf(buf + strlen(buf), " %-14.14s", talents[i]); for (j = 1; j <= 10; j++) { if (GET_TALENT(ch, i) >= j) strcat(buf, "*"); else strcat(buf, " "); } sprintf(buf + strlen(buf), " %-14.14s", skills[i]); for (j = 1; j <= 10; j++) { if (GET_SKILL(ch, i) >= j) strcat(buf, "*"); else strcat(buf, " "); } sprintf(buf + strlen(buf), " %-14.14s", knowledges[i]); for (j = 1; j <= 10; j++) { if (GET_KNOWLEDGE(ch, i) >= j) strcat(buf, "*"); else strcat(buf, " "); } strcat(buf, "\r\n "); msg_to_char(to, buf); } } char *corpse_desc(Object obj, Creature ch) { char name[MAX_INPUT_LENGTH]; static char out[MAX_INPUT_LENGTH]; if (GET_OBJ_VAL(obj, 0) >= 0 && real_mobile(GET_OBJ_VAL(obj, 0)) != NOTHING) strcpy(name, GET_MOB_NAME_BY_PROTO(real_mobile(GET_OBJ_VAL(obj, 0)))); else strcpy(name, "a person"); sprintf(out, "the corpse of %s", name); return out; } char *get_obj_desc(Object obj, Creature ch, int mode) { extern int fill_word(char *argument); extern int reserved_word(char *argument); static char output[MAX_STRING_LENGTH]; char sdesc[MAX_STRING_LENGTH], b1[MAX_STRING_LENGTH], b2[MAX_STRING_LENGTH]; *output = '\0'; /* sdesc will be empty unless the short desc is modified */ *sdesc = '\0'; if (IS_OBJ_STAT(obj, ITEM_SUPERIOR)) { if (!*sdesc) strcpy(sdesc, obj->short_description); half_chop(sdesc, b1, b2); if (fill_word(b1) || reserved_word(b1)) { if (!str_cmp(b1, "an")) strcpy(b1, "a"); sprintf(sdesc, "%s superior %s", b1, b2); } else { strcpy(b1, sdesc); sprintf(sdesc, "superior %s", b1); } } if (IS_CORPSE(obj)) strcpy(sdesc, corpse_desc(obj, ch)); switch (mode) { case 0: /* Long description */ if (*sdesc) sprintf(output, "%s is lying here.", CAP(sdesc)); else strcpy(output, obj->description); break; default: if (*sdesc) strcpy(output, sdesc); else strcpy(output, obj->short_description); break; } return output; } /* * This function screams bitvector... -gg 6/45/98 */ void show_obj_to_char(Object obj, Creature ch, int mode) { extern int Board_show_board(int board_type, Creature ch, char *arg, Object board); extern int board_loaded; void init_boards(void); extern int find_board(Creature ch); int board_type; *buf = '\0'; if (mode == 0) { if (!IN_CHAIR(obj)) strcpy(buf, GET_OBJ_DESC(obj, ch, 0)); else /* It won't get here if I'm not sitting on it */ sprintf(buf, "You are sitting on %s.", GET_OBJ_DESC(obj, ch, 1)); } else if (mode == 1 || mode == 2 || mode == 3 || mode == 4) strcpy(buf, GET_OBJ_DESC(obj, ch, mode)); else if (mode == 5) { if (GET_OBJ_RNUM(obj) != NOTHING && obj_index[GET_OBJ_RNUM(obj)].look_spec && ((obj_index[GET_OBJ_RNUM(obj)].look_spec) (ch, obj, 0))) return; else if (GET_OBJ_TYPE(obj) == ITEM_BOARD) { if (!board_loaded) { init_boards(); board_loaded = 1; } if ((board_type = find_board(ch)) != -1) if (Board_show_board(board_type, ch, "board", obj)) return; strcpy(buf, "You see nothing special.."); } else if (GET_OBJ_TYPE(obj) == ITEM_MAIL) page_string(ch->desc, obj->action_description ? obj->action_description : "It's blank.\r\n", 1); else if (GET_OBJ_TYPE(obj) != ITEM_DRINKCON) strcpy(buf, "You see nothing special.."); else /* ITEM_TYPE == ITEM_DRINKCON */ strcpy(buf, "It looks like a drink container."); } strcat(buf, "\r\n"); page_string(ch->desc, buf, TRUE); } void list_obj_to_char(Object list, Creature ch, int mode, int show) { Object i, j = NULL; bool found = FALSE; int num; for (i = list; i; i = i->next_content) { num = 0; for (j = list; j != i; j = j->next_content) { strcpy(buf, GET_OBJ_DESC(j, ch, 1)); if (!strcmp(buf, GET_OBJ_DESC(i, ch, 1))) { if (j->item_number == NOTHING) break; else if (j->item_number == i->item_number) break; } } if (j != i && GET_OBJ_TYPE(i) != ITEM_CONTAINER) continue; for (j = i; j; j = j->next_content) if (GET_OBJ_TYPE(j) != ITEM_CONTAINER) { strcpy(buf, GET_OBJ_DESC(j, ch, 1)); if (!strcmp(buf, GET_OBJ_DESC(i, ch, 1))) { if (j->item_number == NOTHING) num++; else if (j->item_number == i->item_number) num++; } } if (CAN_SEE_OBJ(ch, i) && (!IN_CHAIR(i) || ch == IN_CHAIR(i))) { if (num > 1) msg_to_char(ch, "%s(%2i) ", mode == 0 ? "&2" : "", num); else msg_to_char(ch, "%s", mode == 0 ? "&2" : ""); show_obj_to_char(i, ch, mode); found = TRUE; } } if (!found && show) msg_to_char(ch, " Nothing.\r\n"); } void diag_char_to_char(Creature i, Creature ch) { strcpy(buf, "$n"); switch (GET_DAMAGE(i)) { case 0: strcat(buf, " is in excellent condition."); break; case 1: strcat(buf, " has some small wounds and bruises."); break; case 2: strcat(buf, " looks hurt."); break; case 3: strcat(buf, " appears injured."); break; case 4: strcat(buf, " is greatly wounded."); break; case 5: strcat(buf, " looks mauled!"); break; case 6: strcat(buf, " is crippled!"); break; case 7: strcat(buf, " is incapacitated!"); break; default: strcat(buf, " is utterly torn up!"); break; } act(buf, FALSE, i, 0, ch, TO_VICT); } void look_at_char(Creature i, Creature ch, bool eq, bool self) { int j, found; if (!ch->desc) return; if (ch == i && !self) { msg_to_char(ch, "Yep, you're still there!\r\n"); return; } act("You look at $N.", FALSE, ch, 0, i, TO_CHAR); if (IS_NPC(i) && GET_MOB_RNUM(i) != NOTHING && mob_index[GET_MOB_RNUM(i)].look_spec && ((mob_index[GET_MOB_RNUM(i)].look_spec) (ch, i, 0))) return; /* For morphs, we'll give a description instead of equipment */ if (!IS_NPC(i) && GET_MORPH(i)) act(morph_string(i, MORPH_STRING_DESC), FALSE, ch, 0, i, TO_CHAR); else { if (!IS_NPC(i)) { *buf = '\0'; /* skin color */ if (!IS_VAMPIRE(i) || DSC_FLAGGED(i, DSC_MASK)) { switch (GET_SKIN(i)) { case SKIN_FAIR: strcat(buf, "$S skin is fair in color."); break; case SKIN_REDDENED: strcat(buf, "$E has reddish skin."); break; case SKIN_YELLOWISH: strcat(buf, "$S skin has a yellow undertone."); break; case SKIN_TAN_LIGHT: strcat(buf, "$E has a lightly tanned complexion."); break; case SKIN_TAN_DARK: strcat(buf, "$S skin has a bronze tone."); break; case SKIN_LIGHT_BROWN: strcat(buf, "$S skin is light brown."); break; case SKIN_DARK_BROWN: strcat(buf, "$S skin is dark brown, almost black."); break; } } else { /* Clan Weakness: Cappadocian */ switch (MIN((GET_CLAN(i) == CLAN_CAPPADOCIAN ? 0 : 10), (GET_BLOOD(i) * 10 / GET_MAX_BLOOD(i)) * GET_HUMANITY(i) / 10)) { case 3: strcat(buf, "$S skin is a pale white, barely even showing veins."); break; case 4: strcat(buf, "$S skin is pale and sickly."); break; case 5: strcat(buf, "$S skin is pale."); break; case 6: strcat(buf, "$S's skin is extremely light pink."); break; case 7: strcat(buf, "$S's skin is light pink."); break; case 8: strcat(buf, "$S skin has a pink tone."); break; case 9: strcat(buf, "$S skin is fair in color."); break; case 10: strcat(buf, "$S skin is flushed a healthy red."); break; default: strcat(buf, "$S skin is chalk-white and even $S veins are invisible through it. It's truly mortifying!"); break; } } /* Clan Weakness: Nosferatu */ if (GET_CLAN(i) == CLAN_NOSFERATU && !DSC_FLAGGED(i, DSC_MASK)) strcat(buf, " $N appears to have leprosy. $S skin is flaking and rotting off!"); if (DSC_FLAGGED(i, DSC_TONGUE_OF_THE_ASP) && ww_dice(GET_PERCEPTION(ch) + GET_OCCULT(ch), 8 - SENSES_BONUS(ch)) >= 1 && !DSC_FLAGGED(i, DSC_MASK)) strcat(buf, " You think you notice a forked tongue in $S mouth!"); /* hair */ switch (GET_HAIR(i)) { case HAIR_BLACK: strcat(buf, " $N's hair is a deep, foreboding black"); break; case HAIR_BROWN: strcat(buf, " Thick, brown hair flows from $S head"); break; case HAIR_BLONDE: strcat(buf, " $N's head is topped with playful, blonde hair"); break; case HAIR_RED: strcat(buf, " $N's hair is a sinister shade of red"); break; case HAIR_WHITE: strcat(buf, " $N's age shows through in $S white hair"); break; case HAIR_GREEN: strcat(buf, " $N has unusually green hair"); break; case HAIR_BLUE: strcat(buf, " $N's hair is a strange shade of blue"); break; } /* eyes */ switch (GET_EYES(i)) { case EYES_BLACK: strcat(buf, " with bottomless, black eyes."); break; case EYES_BROWN: strcat(buf, ", accompanied by dark brown eyes."); break; case EYES_BLUE: strcat(buf, ", accented by shining blue eyes."); break; case EYES_GREEN: strcat(buf, " and $E has vibrant green eyes."); break; case EYES_VIOLET: strcat(buf, " with mysterious, violet eyes."); break; case EYES_RED: strcat(buf, " and $E has flaming red eyes!"); break; } if (HAS_INFRA(i)) strcat(buf, " You notice a distinct, red glint in $S eyes."); if (DSC_FLAGGED(i, DSC_TALONS_OF_THE_BEAST) && !DSC_FLAGGED(i, DSC_MASK)) strcat(buf, " $N's hands are huge, distorted, and very sharp!"); if (ch != i) { if (GET_HEIGHT(i) > GET_HEIGHT(ch)) strcat(buf, " You are shorter than $M"); else strcat(buf, " You are slightly taller than $M"); if (GET_WEIGHT(i) > GET_WEIGHT(ch)) strcat(buf, " and $E is much larger than you."); else strcat(buf, " and $E is smaller than you."); if (DSC_FLAGGED(i, DSC_AWE | DSC_MAJESTY)) strcat(buf, " $N has an aura of awe about $M."); } /* Infernal override: */ if (DSC_FLAGGED(i, DSC_BITUMENOUS_FLESH)) act("$E is mummified in a hard, dark substance!", FALSE, ch, 0, i, TO_CHAR); else { act(buf, FALSE, ch, 0, i, TO_CHAR); diag_char_to_char(i, ch); } } else diag_char_to_char(i, ch); if (!eq) return; 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) { msg_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))) { msg_to_char(ch, where[j]); show_obj_to_char(GET_EQ(i, j), ch, 1); } } } if (!eq) return; if (ch != i && (IS_NPC(i) || GET_MORPH(i) == MORPH_NONE) && (GET_LEVEL(ch) >= LVL_GOD || GET_LARCENY(ch) >= 2)) { act("\r\nYou attempt to peek at $s inventory:", FALSE, i, 0, ch, TO_VICT); list_obj_to_char(i->carrying, ch, 1, TRUE); } } void list_one_char(Creature i, Creature ch, int num) { 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 (num > 1) msg_to_char(ch, "(%2d) ", num); if (AFF_FLAGGED(i, AFF_NO_SEE_IN_ROOM)) return; if (DSC_FLAGGED(i, DSC_MASQUE_OF_DEATH | DSC_DEATHS_WHISPER) && GET_POS(i) <= POS_RESTING) { msg_to_char(ch, "&2The corpse of %s is lying here.&3\r\n", IS_NPC(i) ? PERS(i, i, 0) : "a human"); return; } if (IS_NPC(i) && i->player.long_descr && GET_POS(i) == POS_STANDING) { if (AFF_FLAGGED(i, AFF_INVISIBLE)) msg_to_char(ch, "*"); msg_to_char(ch, i->player.long_descr); } else { if (IS_NPC(i)) { strcpy(buf, i->player.short_descr); CAP(buf); } else { if (AFF_FLAGGED(i, AFF_INVISIBLE)) strcpy(buf, "*"); else *buf = '\0'; sprintf(buf1, PERS(i, ch, 0)); strcat(buf, CAP(buf1)); switch (GET_SEX(i)) { case SEX_MALE: strcpy(buf1, "man"); break; case SEX_FEMALE: strcpy(buf1, "woman"); break; default: strcpy(buf1, "person"); break; } if (GET_MORPH(i) == MORPH_NONE) switch (DSC_FLAGGED(i, DSC_MASK) ? MAX(4, GET_APPEARANCE(i)) : GET_APPEARANCE(i)) { case 0: sprintf(buf + strlen(buf), ", a hideously ugly %s,", buf1); break; case 1: sprintf(buf + strlen(buf), ", an ugly %s,", buf1); break; case 2: break; case 3: sprintf(buf + strlen(buf), ", a comely %s,", buf1); break; case 4: sprintf(buf + strlen(buf), ", an attractive %s,", buf1); break; default: sprintf(buf + strlen(buf), ", a very attractive %s,", buf1); break; } } if (AFF_FLAGGED(i, AFF_HIDE)) strcat(buf, " (hidden)"); if (!IS_NPC(i) && !i->desc) strcat(buf, " (linkless)"); if (!IS_NPC(i) && PLR_FLAGGED(i, PLR_WRITING)) strcat(buf, " (writing)"); if (GET_POS(i) != POS_FIGHTING) { if (!ON_CHAIR(i)) strcat(buf, positions[(int) GET_POS(i)]); else sprintf(buf + strlen(buf), " is sitting on %s.", CAN_SEE_OBJ(ch, ON_CHAIR(i)) ? GET_OBJ_DESC(ON_CHAIR(i), ch, 1) : "something"); } else { if (FIGHTING(i)) { strcat(buf, " is here, fighting "); if (FIGHTING(i) == ch) strcat(buf, "YOU!"); else { if (i->in_room == FIGHTING(i)->in_room) strcat(buf, PERS(FIGHTING(i), ch, 0)); else strcat(buf, "someone who has already left"); strcat(buf, "!"); } } else /* NIL fighting pointer */ strcat(buf, " is here struggling with thin air."); } msg_to_char(ch, "%s\r\n", buf); } if (GET_RIDING(i)) { sprintf(buf, "...%s is mounted upon $N.", HSSH(i)); act(buf, FALSE, ch, 0, GET_RIDING(i), TO_CHAR); } if (GET_LED_BY(i)) { sprintf(buf, "...%s is being led by %s.", HSSH(i), GET_LED_BY(i) == ch ? "you" : "$N"); act(buf, FALSE, ch, 0, GET_LED_BY(i), TO_CHAR); } if (MOB_FLAGGED(i, MOB_TIED)) act("...$e is tied up here.", FALSE, i, 0, ch, TO_VICT); if (DSC_FLAGGED(i, DSC_MASQUE_OF_DEATH)) act("...$e is a walking corpse!", FALSE, i, 0, ch, TO_VICT); if (!IS_NPC(i) && GET_SLIT_WRIST(i)) act("...$s wrist has been cut open and is dripping blood!", FALSE, i, 0, ch, TO_VICT); if (AFF_FLAGGED(i, AFF_BLIND)) act("...$e is groping around blindly!", FALSE, i, 0, ch, TO_VICT); if (IS_INJURED(i, INJ_TIED)) act("...$e is bound and gagged!", FALSE, i, 0, ch, TO_VICT); if (IS_INJURED(i, INJ_STAKED)) act("...$e has a stake through $s heart!", FALSE, i, 0, ch, TO_VICT); if (DSC_FLAGGED(i, DSC_BITUMENOUS_FLESH)) act("...$e is mummified in a hard outer covering!", FALSE, i, 0, ch, TO_VICT); if (IS_VAMPIRE(i) && HAS_INFRA(i)) act("...$s eyes have an eerie, red glow!", FALSE, i, 0, ch, TO_VICT); if (DSC_FLAGGED(i, DSC_TALONS_OF_THE_BEAST) && !DSC_FLAGGED(i, DSC_MASK)) act("...$s fingers are mutated into giant, hideous talons!", FALSE, i, 0, ch, TO_VICT); if (DSC_FLAGGED(i, DSC_AWE)) act("...$e is surrounded by an awesome aura!", FALSE, i, 0, ch, TO_VICT); if (DSC_FLAGGED(i, DSC_MAJESTY)) act("...$e has a majestic aura about $m!", FALSE, i, 0, ch, TO_VICT); if (PLR_FLAGGED(i, PLR_PIRATE)) act("...$e has a tattoo of a pirate!", FALSE, i, 0, ch, TO_VICT); if (!IS_NPC(i) && GET_DAYS_SINCE_BATHING(i) > 3) { switch (GET_DAYS_SINCE_BATHING(i)) { case 4: act("...$e has a putrid smell about $m.", FALSE, i, 0, ch, TO_VICT); break; case 5: act("...a cloud of flies is circling around $m.", FALSE, i, 0, ch, TO_VICT); break; case 6: act("...$e is extremely dirty, and smells disgusting!", FALSE, i, 0, ch, TO_VICT); break; case 7: act("...$e is filthy, and smells like manure!", FALSE, i, 0, ch, TO_VICT); break; default: act("...$e is absolutely revolting!", FALSE, i, 0, ch, TO_VICT); break; } } if (GET_FED_ON_BY(i)) { sprintf(buf, "...$e is held held tightly by %s!", PERS(GET_FED_ON_BY(i), ch, 0)); act(buf, FALSE, i, 0, ch, TO_VICT); } if (GET_FEEDING_FROM(i)) { sprintf(buf, "...$e has his teeth firmly implanted in %s!", PERS(GET_FEEDING_FROM(i), ch, 0)); act(buf, FALSE, i, 0, ch, TO_VICT); } if (!IS_NPC(i) && GET_ACTION(i) == ACT_MORPHING) act("...$e is undergoing a hideous transformation!", FALSE, i, 0, ch, TO_VICT); if (IS_INJURED(i, INJ_TORPOR)) act("...$e appears to be in torpor!", FALSE, i, 0, ch, TO_VICT); if (((IS_WEREWOLF(i) && IS_WEREWOLF(ch)) || IS_IMMORTAL(ch)) && !IS_NPC(i) && GET_MORPH(i) != MORPH_NONE) act("...this appears to be $o.", FALSE, i, 0, ch, TO_VICT); } void list_char_to_char(Creature list, Creature ch) { Creature i, j; int c = 1; for (i = list; i; i = i->next_in_room, c = 1) if (ch != i) { if (GET_RIDDEN_BY(i)) continue; if (IS_NPC(i) && GET_POS(i) != POS_FIGHTING) { for (j = list; j != i; j = j->next_in_room) if (GET_MOB_VNUM(j) == GET_MOB_VNUM(i) && !GET_RIDDEN_BY(j) && CAN_SEE(ch, j) && GET_POS(j) == GET_POS(i) && GET_POS(j) != POS_FIGHTING) break; if (j != i) continue; for (j = i->next_in_room; j; j = j->next_in_room) if (GET_MOB_VNUM(j) == GET_MOB_VNUM(i) && !GET_RIDDEN_BY(j) && CAN_SEE(ch, j) && GET_POS(j) == GET_POS(i) && GET_POS(j) != POS_FIGHTING) c++; } if (CAN_SEE(ch, i)) list_one_char(i, ch, c); else if (!CAN_SEE_IN_DARK_ROOM(ch, ch->in_room) && HAS_INFRA(i) && !NOCTURNE_DARK(ch->in_room)) { if (c > 1) msg_to_char(ch, "(%2d) ", c); msg_to_char(ch, "You see a pair of glowing red eyes looking your way.\r\n"); } } } ACMD(do_weather) { void list_moons_to_char(Creature ch); const char *sky_look[] = { "cloudless", "cloudy", "rainy", "lit by flashes of lightning" }; if (IS_OUTDOORS(ch)) { msg_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 (weather_info.sunlight == SUN_SET || weather_info.sunlight == SUN_DARK) list_moons_to_char(ch); } else msg_to_char(ch, "You can't see the sky from here.\r\n"); } ACMD(do_exits) { extern char *get_room_name(int room, bool color); int door, room; if (subcmd == -1) room = ch->in_room; else room = subcmd; *buf = '\0'; if (AFF_FLAGGED(ch, AFF_BLIND)) { msg_to_char(ch, "You can't see a damned thing, you're blind!\r\n"); return; } for (door = 0; door < NUM_OF_DIRS; door++) if (world[room].dir_option[door] && world[room].dir_option[door]->to_room != NOWHERE && !EXIT_FLAGGED(world[room].dir_option[door], EX_CLOSED)) { sprintf(buf2, "%-5s - ", dirs[door]); if (!CAN_SEE_IN_DARK_ROOM(ch, world[room].dir_option[door]->to_room)) strcat(buf2, "Too dark to tell\r\n"); else sprintf(buf2 + strlen(buf2), "%s\r\n", get_room_name(world[room].dir_option[door]->to_room, 0)); strcat(buf, CAP(buf2)); } msg_to_char(ch, "Obvious exits:\r\n%s", *buf ? buf : "None.\r\n"); } void show_map_to_char(Creature ch, room_rnum room, int shift_x, int shift_y) { extern bool show_pc_in_room(Creature ch, room_rnum room); extern const char *sector_disp[]; extern const char *building_disp[]; extern const char *crop_disp[]; extern const char *open_monument_icons[]; extern const char *closed_monument_icons[]; extern const char *multi_disp[][3]; char buf[30], buf1[30]; room_rnum to_room = real_shift(room, shift_x, shift_y); int i, j; bool hidden = FALSE; #define distance(x, y, a, b) ((x - a) * (x - a) + (y - b) * (y - b)) *buf = '\0'; if (shift_x == 0 && shift_y == 0) strcpy(buf, "&0<oo>"); else if (show_pc_in_room(ch, real_shift(room, shift_x, shift_y))) return; /* Hidden buildings */ else if (distance(FLAT_X_COORD(ch->in_room), FLAT_Y_COORD(ch->in_room), FLAT_X_COORD(to_room), FLAT_Y_COORD(to_room)) > 2 && ROOM_AFF_FLAGGED(to_room, ROOM_AFF_CHAMELEON_FOREST | ROOM_AFF_CHAMELEON_DESERT | ROOM_AFF_CHAMELEON_MOUNTAIN)) { if (ROOM_AFF_FLAGGED(to_room, ROOM_AFF_CHAMELEON_FOREST)) strcat(buf, sector_disp[SECT_FOREST_4]); else if (ROOM_AFF_FLAGGED(to_room, ROOM_AFF_CHAMELEON_DESERT)) strcat(buf, sector_disp[SECT_DESERT]); else if (ROOM_AFF_FLAGGED(to_room, ROOM_AFF_CHAMELEON_MOUNTAIN)) strcat(buf, sector_disp[SECT_MOUNTAIN]); hidden = TRUE; } /* Rooms with custom icons (take precedence over all but hidden rooms */ else if (world[to_room].icon) strcat(buf, world[to_room].icon); else if (SECT(to_room) == SECT_BARRIER) { if (world[to_room].type2 == 0) strcpy(buf, "&0"); else if (world[to_room].type2 == 1) strcpy(buf, "&2"); else if (world[to_room].type2 == 2) strcpy(buf, "&3"); if (world[to_room].type == 1) { if (SECT(shift_w(to_room)) == SECT_BARRIER || BUILDING_TYPE(shift_w(to_room)) == BUILDING_GATEHOUSE) strcat(buf, "VV"); else strcat(buf, ".V"); if (SECT(shift_e(to_room)) == SECT_BARRIER || BUILDING_TYPE(shift_e(to_room)) == BUILDING_GATEHOUSE) strcat(buf, "VV"); else strcat(buf, "V."); } else { if (SECT(shift_w(to_room)) == SECT_BARRIER || BUILDING_TYPE(shift_w(to_room)) == BUILDING_GATEHOUSE) strcat(buf, "vv"); else strcat(buf, ".v"); if (SECT(shift_e(to_room)) == SECT_BARRIER || BUILDING_TYPE(shift_e(to_room)) == BUILDING_GATEHOUSE) strcat(buf, "vv"); else strcat(buf, "v."); } } else if (BUILDING_TYPE(to_room) == BUILDING_GATEHOUSE) { strcpy(buf, "&0"); if ((world[to_room].building_entrance == NORTH || world[to_room].building_entrance == SOUTH) && (SECT(shift_w(to_room)) == SECT_BARRIER && !world[shift_w(to_room)].type)) strcat(buf, "v"); else if ((world[to_room].building_entrance == SOUTH || world[to_room].building_entrance == NORTH) && (SECT(shift_w(to_room)) == SECT_BARRIER && world[shift_w(to_room)].type)) strcat(buf, "V"); else if ((world[to_room].building_entrance == EAST || world[to_room].building_entrance == WEST) && SECT(shift_w(to_room)) == SECT_ROAD) strcat(buf, "-"); else strcat(buf, "."); if (world[to_room].building_entrance == WEST || world[to_room].building_entrance == EAST) strcat(buf, "=="); else if (world[to_room].building_entrance == NORTH || world[to_room].building_entrance == SOUTH) strcat(buf, "||"); else if (world[to_room].building_entrance == NORTHWEST || world[to_room].building_entrance == SOUTHEAST) strcat(buf, "\\\\"); else if (world[to_room].building_entrance == SOUTHWEST || world[to_room].building_entrance == NORTHEAST) strcat(buf, "//"); if ((world[to_room].building_entrance == NORTH || world[to_room].building_entrance == SOUTH) && (SECT(shift_e(to_room)) == SECT_BARRIER && !world[shift_e(to_room)].type)) strcat(buf, "v"); else if ((world[to_room].building_entrance == SOUTH || world[to_room].building_entrance == NORTH) && (SECT(shift_e(to_room)) == SECT_BARRIER && world[shift_e(to_room)].type)) strcat(buf, "V"); else if ((world[to_room].building_entrance == EAST || world[to_room].building_entrance == WEST) && SECT(shift_e(to_room)) == SECT_ROAD) strcat(buf, "-"); else strcat(buf, "."); } else if (SECT(to_room) == SECT_ROAD) { *buf = '\0'; if (SECT(shift_w(to_room)) == SECT_ROAD || BUILDING_TYPE(shift_w(to_room)) == BUILDING_GATEHOUSE) strcat(buf, "&0--"); else if (SECT(shift_n(to_room)) == SECT_ROAD || SECT(shift_s(to_room)) == SECT_ROAD || BUILDING_TYPE(shift_n(to_room)) == BUILDING_GATEHOUSE || BUILDING_TYPE(shift_s(to_room)) == BUILDING_GATEHOUSE) { if (world[to_room].type) strcat(buf, "&4~~&0"); else strcat(buf, "&0.."); } else if (world[to_room].type) strcat(buf, "&4~&0-"); else strcat(buf, "&0.-"); if (SECT(shift_n(to_room)) == SECT_ROAD || SECT(shift_s(to_room)) == SECT_ROAD || BUILDING_TYPE(shift_n(to_room)) == BUILDING_GATEHOUSE ||BUILDING_TYPE(shift_s(to_room)) == BUILDING_GATEHOUSE) { if (strstr(buf, "-") || SECT(shift_e(to_room)) == SECT_ROAD) strcat(buf, "+"); else strcat(buf, "|"); } else strcat(buf, "-"); if (SECT(shift_e(to_room)) == SECT_ROAD || BUILDING_TYPE(shift_e(to_room)) == BUILDING_GATEHOUSE) strcat(buf, "-"); else if (world[to_room].type) strcat(buf, "&4~"); else strcat(buf, "."); if (world[to_room].type2) for (i = 0; i < strlen(buf); i++) if (buf[i] == '0') buf[i] = '3'; } else if (BUILDING_TYPE(to_room) == BUILDING_SHIPYARD || BUILDING_TYPE(to_room) == BUILDING_SHIPYARD2) { if (world[to_room].building_entrance == NORTH || world[to_room].building_entrance == NORTHEAST || world[to_room].building_entrance == EAST || world[to_room].building_entrance == SOUTHEAST || world[to_room].building_entrance == SOUTH) strcpy(buf, "&4~"); else strcpy(buf, "&0."); if (BUILDING_TYPE(to_room) == BUILDING_SHIPYARD) strcat(buf, "&0()"); else strcat(buf, "&0[]"); if (world[to_room].building_entrance == NORTH || world[to_room].building_entrance == NORTHWEST || world[to_room].building_entrance == WEST || world[to_room].building_entrance == SOUTHWEST || world[to_room].building_entrance == SOUTH) strcat(buf, "&4~"); else strcat(buf, "."); } else if (BUILDING_TYPE(to_room) == BUILDING_DOCKS) { if (world[to_room].building_entrance == NORTHEAST || world[to_room].building_entrance == EAST || world[to_room].building_entrance == SOUTHEAST) strcpy(buf, "&4~~&0=="); else if (world[to_room].building_entrance == NORTH || world[to_room].building_entrance == SOUTH) strcpy(buf, "&4~&0==&4~"); else strcpy(buf, "&0==&4~~"); } /* Altered icons */ else if (BUILDING_TYPE(to_room) == BUILDING_GUARD_TOWER && world[to_room].type2 == 2) strcat(buf, "&3.&0TT&3."); else if (SECT(to_room) == SECT_BUILDING) strcat(buf, building_disp[(int) world[to_room].type]); else if (SECT(to_room) == SECT_MULTI) strcat(buf, multi_disp[(int) world[to_room].type][(int) world[to_room].type2]); else if (SECT(to_room) == SECT_FOREST_1 && world[to_room].type2) { switch (number(0, 3)) { case 0: strcat(buf, "&2^&3..."); break; case 1: strcat(buf, "&3.&2^&3.."); break; case 2: strcat(buf, "&3..&2^&3."); break; case 3: strcat(buf, "&3...&2^"); break; } } else if (SECT(to_room) == SECT_CROP && world[to_room].type == CROP_FRUIT) { switch (number(0, 9)) { case 0: strcat(buf, "&1o&3^^^"); break; case 1: strcat(buf, "&3^&1o&3^^"); break; case 2: strcat(buf, "&3^^&1o&3^"); break; case 3: strcat(buf, "&3^^^&1o"); break; default: strcat(buf, crop_disp[(int) world[to_room].type]); break; } } else if (SECT(to_room) == SECT_CROP) strcat(buf, crop_disp[(int) world[to_room].type]); else if (SECT(to_room) == SECT_MONUMENT_OPEN) strcat(buf, open_monument_icons[(int) world[to_room].type]); else if (SECT(to_room) == SECT_MONUMENT_CLOSED) strcat(buf, closed_monument_icons[(int) world[to_room].type]); else strcat(buf, sector_disp[(int) SECT(to_room)]); if (PRF_FLAGGED(ch, PRF_NOMAPCOL) || PRF_FLAGGED(ch, PRF_POLITICAL)) { for (i = 0, j = 0; i < strlen(buf); i++) { if (buf[i] == '&') i++; else buf1[j++] = buf[i]; } buf1[4] = '\0'; /* world[to_room].owner == -1 is a key for unclaimable */ if (PRF_FLAGGED(ch, PRF_POLITICAL) && !hidden) sprintf(buf, "%s%s&0", world[to_room].owner != -1 && real_empire(world[to_room].owner) != -1 && empire[real_empire(world[to_room].owner)].banner ? empire[real_empire(world[to_room].owner)].banner : "&0", buf1); else strcpy(buf, buf1); } send_to_char(buf, ch); } bool show_pc_in_room(Creature ch, room_rnum room) { Creature c; if (!PRF_FLAGGED(ch, PRF_MAPPC)) return FALSE; if (SECT(room) == SECT_MONUMENT_CLOSED || SECT(room) == SECT_BUILDING || SECT(room) == SECT_MULTI || SECT(room) == SECT_MOUNTAIN || SECT(room) == SECT_FOREST_4) if (IS_COMPLETE(room) || ALWAYS_CLOSED(room)) return FALSE; /* Hidden people are left off the map, even if you sense life */ for (c = world[room].people; c; c = c->next_in_room) if (!IS_NPC(c) && CAN_SEE(ch, c) && !AFF_FLAGGED(c, AFF_NO_SEE_IN_ROOM) && !MORPH_FLAGGED(c, MORPH_FLAG_NPC) && (!AFF_FLAGGED(c, AFF_HIDE) || IS_GOD(ch) || IS_IMMORTAL(ch))) { msg_to_char(ch, "&0<oo>"); return TRUE; } return FALSE; } bool adjacent_room_is_light(room_rnum room) { int i; for (i = 0; i < NUM_SIMPLE_DIRS; i++) if (IS_REAL_LIGHT(real_shift(room, shift_dir[i][0], shift_dir[i][1]))) return 1; return 0; } char *get_room_name(int room, bool color) { extern const char *multi_entrance_names[]; extern const char *building_names[]; extern const char *room_names[]; extern const char *crop_names[]; extern const char *open_monument_names[]; extern const char *closed_monument_names[]; static char name[MAX_STRING_LENGTH]; /* world[room].owner == -1 is a key for unclaimable */ if (real_empire(world[room].owner) != -1 && world[room].owner != -1 && color) strcpy(name, empire[real_empire(world[room].owner)].banner); else *name = '\0'; /* Note: room names ALWAYS override other names */ if (world[room].name) strcat(name, world[room].name); /* Names by type */ else if (SECT(room) == SECT_INSIDE) strcat(name, room_names[(int) world[room].type]); else if (SECT(room) == SECT_CROP) strcat(name, crop_names[(int) world[room].type]); /* Custom names by type */ else if ((BUILDING_TYPE(room) == BUILDING_GUARD_TOWER2 || BUILDING_TYPE(room) == BUILDING_GUARD_TOWER3 || BUILDING_TYPE(room) == BUILDING_GUARD_TOWER) && world[room].type2 == 2 && IS_COMPLETE(room)) strcat(name, "A Desert Sentry"); else if (SECT(room) == SECT_FOREST_1 && world[room].type2) strcat(name, "A Palm Tree"); /* Building */ else if (SECT(room) == SECT_BUILDING) strcat(name, building_names[(int) world[room].type]); /* Wall */ else if (SECT(room) == SECT_BARRIER) { if (world[room].type2 == 0) sprintf(name + strlen(name), "%s", world[room].type ? "A Stone Wall" : "A Rickety Fence"); else if (world[room].type2 == 1) sprintf(name + strlen(name), "%s", world[room].type ? "A Rocky Palisade" : "An Inpenetrable Trellis"); else if (world[room].type2 == 2) sprintf(name + strlen(name), "%s", world[room].type ? "An Adobe Wall" : "A Spiked Barrier"); } /* Closed Monuments */ else if (CLOSED_MONUMENT_TYPE(room) == MONUMENT_C_SHRINE) sprintf(name + strlen(name), "A Shrine to %s", get_name_by_id(world[room].spare) ? CAP(get_name_by_id(world[room].spare)) : "a Former God"); else if (CLOSED_MONUMENT_TYPE(room) == MONUMENT_C_TEMPLE_UL) sprintf(name + strlen(name), "A Temple of %s", get_name_by_id(world[room].spare) ? CAP(get_name_by_id(world[room].spare)) : "a Former God"); else if (CLOSED_MONUMENT_TYPE(room) == MONUMENT_C_HIGHTEMPLE_UC) sprintf(name + strlen(name), "A Temple of %s", get_name_by_id(world[room].spare) ? CAP(get_name_by_id(world[room].spare)) : "a Former God"); else if (SECT(room) == SECT_MONUMENT_CLOSED) strcat(name, closed_monument_names[(int) world[room].type]); /* Open Monuments */ else if (OPEN_MONUMENT_TYPE(room) == MONUMENT_O_STATUE) sprintf(name + strlen(name), "A Statue of %s", get_name_by_id(world[room].spare) ? CAP(get_name_by_id(world[room].spare)) : "a Former God"); else if (SECT(room) == SECT_MONUMENT_OPEN) strcat(name, open_monument_names[(int) world[room].type]); /* Multi- */ else if (SECT(room) == SECT_MULTI) strcat(name, multi_entrance_names[(int) world[room].type2]); /* Normal */ else strcat(name, sector_name[(int) SECT(room)]); return (name); } char *get_room_description(int room) { extern const char *multi_entrance_descriptions[]; extern const char *building_descs[]; extern const char *room_descs[]; extern const char *closed_monument_description[]; static char desc[MAX_STRING_LENGTH]; *desc = '\0'; /* Note: room descs ALWAYS override other descs */ if (world[room].description) strcat(desc, world[room].description); else if (SECT(room) == SECT_BUILDING && (ALWAYS_CLOSED(room) || IS_COMPLETE(room))) strcat(desc, building_descs[(int) world[room].type]); else if (SECT(room) == SECT_INSIDE) strcat(desc, room_descs[(int) world[room].type]); else if (SECT(room) == SECT_MULTI && IS_COMPLETE(room)) strcat(desc, multi_entrance_descriptions[(int) world[room].type2]); else if (SECT(room) == SECT_MONUMENT_CLOSED) strcat(desc, closed_monument_description[(int) world[room].type]); else return NULL; return (desc); } #define AbsMax(x, y) MAX(((x) < 0 ? (-1 * x) : (x)), ((y) < 0 ? (-1 * y) : (y))) void look_at_room_by_rnum(Creature ch, room_rnum room) { extern byte distance_can_see(Creature ch); extern char *get_name_by_id(long id); char output[MAX_STRING_LENGTH]; int i, j, s, t; if (!ch || !ch->desc) return; if (AFF_FLAGGED(ch, AFF_BLIND)) { msg_to_char(ch, "You see nothing but infinite darkness...\r\n"); return; } if (DSC_FLAGGED(ch, DSC_EARTHMELD) && (SECT(ch->in_room) == SECT_BUILDING || SECT(ch->in_room) == SECT_MULTI || SECT(ch->in_room) == SECT_MONUMENT_CLOSED)) { msg_to_char(ch, "You are beneath a building.\r\n"); return; } sprintf(output, "%s (%d, %d)&0", get_room_name(room, 1), X_COORD(room), Y_COORD(room)); if (!PRF_FLAGGED(ch, PRF_BRIEF) && get_room_description(room)) sprintf(output + strlen(output), "\r\n%s", get_room_description(room)); else strcat(output, "\r\n"); if (!PRF_FLAGGED(ch, PRF_NOCLEAR)) msg_to_char(ch, "[H[J"); if ((SECT(room) != SECT_BUILDING && SECT(room) != SECT_MONUMENT_CLOSED && SECT(room) != SECT_MULTI && SECT(room) != SECT_INSIDE) || !(IS_COMPLETE(room) || ALWAYS_CLOSED(room))) { *buf = '\0'; s = (62 - strlen(output))/2; if (!PRF_FLAGGED(ch, PRF_BRIEF)) for (t = 1; t <= s; t++) send_to_char(" ", ch); msg_to_char(ch, output); if (PRF_FLAGGED(ch, PRF_BRIEF)) msg_to_char(ch, "+----------------------------+\r\n"); else msg_to_char(ch, "+------------------------------------------------------------+\r\n"); for (i = (PRF_FLAGGED(ch, PRF_BRIEF) ? 3 : 7); i > (PRF_FLAGGED(ch, PRF_BRIEF) ? -4 : -8); i--) { /* Rows */ msg_to_char(ch, "|"); for (j = (PRF_FLAGGED(ch, PRF_BRIEF) ? -3 : -7); j < (PRF_FLAGGED(ch, PRF_BRIEF) ? 4 : 8); j++) { /* Columns */ if ((!CAN_SEE_IN_DARK_ROOM(ch, real_shift(room, j, i)) && AbsMax(j, i) > distance_can_see(ch) && !adjacent_room_is_light(real_shift(room, j, i))) || ROOM_AFF_FLAGGED(real_shift(room, j, i), ROOM_AFF_DARK)) send_to_char(" ", ch); else if (ROOM_AFF_FLAGGED(real_shift(room, j, i), ROOM_AFF_DARK)) send_to_char(" ", ch); else show_map_to_char(ch, room, j, i); } msg_to_char(ch, "&0|\r\n"); } if (PRF_FLAGGED(ch, PRF_BRIEF)) msg_to_char(ch, "+----------------------------+\r\n"); else msg_to_char(ch, "+------------------------------------------------------------+\r\n"); } else { if (!CAN_SEE_IN_DARK_ROOM(ch, room)) send_to_char("It is pitch black...\r\n", ch); else msg_to_char(ch, output); } /* world[HOME_ROOM(room)].owner == -1 is a key for unclaimable */ if (real_empire(world[HOME_ROOM(room)].owner) != -1 && world[HOME_ROOM(room)].owner != -1) msg_to_char(ch, "This area is owned by %s%s&0.\r\n", empire[real_empire(world[HOME_ROOM(room)].owner)].banner, empire[real_empire(world[HOME_ROOM(room)].owner)].name); if (!IS_COMPLETE(room)) { msg_to_char(ch, "Remaining to Completion:"); if (world[room].res.sticks) msg_to_char(ch, " Sticks: %d", world[room].res.sticks); if (world[room].res.logs) msg_to_char(ch, " Logs: %d", world[room].res.logs); if (world[room].res.rocks) msg_to_char(ch, " Rocks: %d", world[room].res.rocks); if (world[room].res.iron) msg_to_char(ch, " Iron: %d", world[room].res.iron); msg_to_char(ch, "\r\n"); } if (!DSC_FLAGGED(ch, DSC_EARTHMELD)) { /* now list characters & objects */ send_to_char("&2", ch); list_obj_to_char(world[room].contents, ch, 0, FALSE); send_to_char("&3", ch); list_char_to_char(world[room].people, ch); send_to_char("&0", ch); } /* Exits ? */ if ((SECT(room) == SECT_BUILDING || SECT(room) == SECT_MONUMENT_CLOSED || SECT(room) == SECT_MULTI || SECT(room) == SECT_INSIDE) && (IS_COMPLETE(room) || ALWAYS_CLOSED(room))) do_exits(ch, "", 0, room); } void look_in_direction(Creature ch, int dir) { Creature c; int i; room_rnum to_room; if ((SECT(ch->in_room) == SECT_BUILDING || SECT(ch->in_room) == SECT_MONUMENT_CLOSED || SECT(ch->in_room) == SECT_MULTI || SECT(ch->in_room) == SECT_INSIDE) && (IS_COMPLETE(ch->in_room) || ALWAYS_CLOSED(ch->in_room))) { if (EXIT(ch, dir)) { if (EXIT_FLAGGED(EXIT(ch, dir), EX_CLOSED) && EXIT(ch, dir)->keyword) { sprintf(buf, "The %s is closed.\r\n", fname(EXIT(ch, dir)->keyword)); send_to_char(buf, ch); } else if (EXIT_FLAGGED(EXIT(ch, dir), EX_ISDOOR) && EXIT(ch, dir)->keyword) { sprintf(buf, "The %s is open.\r\n", fname(EXIT(ch, dir)->keyword)); send_to_char(buf, ch); } if (!EXIT_FLAGGED(EXIT(ch, dir), EX_CLOSED)) { *buf = '\0'; to_room = EXIT(ch, dir)->to_room; if (CAN_SEE_IN_DARK_ROOM(ch, to_room)) for (c = world[to_room].people; c; c = c->next_in_room) if (CAN_SEE(ch, c)) sprintf(buf+strlen(buf), "%s, ", PERS(c, c, 0)); /* Now, we clean up that buf */ if (*buf) { sprintf(buf+strlen(buf)-2, ".\r\n"); for (i = strlen(buf)-1; i > 0; i--) if (buf[i] == ',') { sprintf(buf1, buf + i+1); buf[i] = '\0'; strcat(buf, " and"); strcat(buf, buf1); break; } msg_to_char(ch, "You see %s", buf); } else msg_to_char(ch, "You don't see anyone in that direction.\r\n"); } } else send_to_char("Nothing special there...\r\n", ch); } else { *buf = '\0'; if (dir == UP) { do_weather(ch, "", 0, 0); return; } if (dir == DOWN) { switch(SECT(ch->in_room)) { case SECT_BUILDING: case SECT_MULTI: case SECT_INSIDE: msg_to_char(ch, "The floor is made of wood.\r\n"); break; case SECT_MONUMENT_CLOSED: case SECT_MONUMENT_OPEN: msg_to_char(ch, "The floor is made of stone.\r\n"); break; case SECT_FOUNTAIN: msg_to_char(ch, "The water in the fountain is clear.\r\n"); break; case SECT_WELL: msg_to_char(ch, "The water in the well is clear.\r\n"); break; case SECT_SEEDED: case SECT_CROP: msg_to_char(ch, "The crops are growing nicely this year.\r\n"); break; case SECT_RIVER: case SECT_OCEAN: msg_to_char(ch, "The flowing waves make you queasy.\r\n"); break; case SECT_ROAD: msg_to_char(ch, "The road is cobbled with stones.\r\n"); break; default: msg_to_char(ch, "The ground is covered with dirt and with grass.\r\n"); break; } return; } to_room = real_shift(ch->in_room, shift_dir[dir][0], shift_dir[dir][1]); if (SECT(to_room) == SECT_MOUNTAIN || SECT(to_room) == SECT_BUILDING || SECT(to_room) == SECT_MONUMENT_CLOSED || SECT(to_room) == SECT_MONUMENT_OPEN || SECT(to_room) == SECT_MULTI) { msg_to_char(ch, "You can't see past the %s.\r\n", SECT(to_room) == SECT_BUILDING || SECT(to_room) == SECT_MULTI ? "building" : "mountains"); return; } if (CAN_SEE_IN_DARK_ROOM(ch, to_room)) for (c = world[to_room].people; c; c = c->next_in_room) if (CAN_SEE(ch, c)) sprintf(buf+strlen(buf), "%s, ", PERS(c, c, 0)); /* Shift, rinse, repeat */ to_room = real_shift(to_room, shift_dir[dir][0], shift_dir[dir][1]); if (SECT(to_room) != SECT_MOUNTAIN && SECT(to_room) != SECT_BUILDING && SECT(to_room) != SECT_MONUMENT_CLOSED && SECT(to_room) != SECT_MONUMENT_OPEN && SECT(to_room) != SECT_MULTI) { if (CAN_SEE_IN_DARK_ROOM(ch, to_room)) for (c = world[to_room].people; c; c = c->next_in_room) if (CAN_SEE(ch, c)) sprintf(buf+strlen(buf), "%s, ", PERS(c, c, 0)); /* And a third time for good measure */ to_room = real_shift(to_room, shift_dir[dir][0], shift_dir[dir][1]); if (SECT(to_room) != SECT_MOUNTAIN && SECT(to_room) != SECT_BUILDING && SECT(to_room) != SECT_MONUMENT_CLOSED && SECT(to_room) != SECT_MONUMENT_OPEN && SECT(to_room) != SECT_MULTI) { if (CAN_SEE_IN_DARK_ROOM(ch, to_room)) for (c = world[to_room].people; c; c = c->next_in_room) if (CAN_SEE(ch, c)) sprintf(buf+strlen(buf), "%s, ", PERS(c, c, 0)); } } /* Now, we clean up that buf */ if (*buf) { sprintf(buf+strlen(buf)-2, ".\r\n"); for (i = strlen(buf)-1; i > 0; i--) if (buf[i] == ',') { sprintf(buf1, buf + i+1); buf[i] = '\0'; strcat(buf, " and"); strcat(buf, buf1); break; } msg_to_char(ch, "You see %s", buf); } else msg_to_char(ch, "You don't see anyone in that direction.\r\n"); } } void look_in_obj(Creature ch, char *arg) { extern const char *color_liquid[]; extern const char *fullness[]; Object obj = NULL; Creature dummy = NULL; int amt, bits; if (!*arg) send_to_char("Look in what?\r\n", ch); else if (!(bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP, ch, &dummy, &obj))) { sprintf(buf, "There doesn't seem to be %s %s here.\r\n", AN(arg), arg); send_to_char(buf, ch); } else if ((GET_OBJ_TYPE(obj) != ITEM_DRINKCON) && (GET_OBJ_TYPE(obj) != ITEM_CORPSE) && (GET_OBJ_TYPE(obj) != ITEM_CONTAINER) && (GET_OBJ_TYPE(obj) != ITEM_CART)) send_to_char("There's nothing inside that!\r\n", ch); else { if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER || GET_OBJ_TYPE(obj) == ITEM_CORPSE || GET_OBJ_TYPE(obj) == ITEM_CART) { if (OBJVAL_FLAGGED(obj, CONT_CLOSED) && GET_OBJ_TYPE(obj) != ITEM_CORPSE && GET_OBJ_TYPE(obj) != ITEM_CART) send_to_char("It is closed.\r\n", ch); else { send_to_char(fname(obj->name), ch); switch (bits) { case FIND_OBJ_INV: send_to_char(" (carried): \r\n", ch); break; case FIND_OBJ_ROOM: send_to_char(" (here): \r\n", ch); break; case FIND_OBJ_EQUIP: send_to_char(" (used): \r\n", ch); break; } list_obj_to_char(obj->contains, ch, 2, TRUE); } } else { /* item must be a fountain or drink container */ if (GET_OBJ_VAL(obj, 1) <= 0) send_to_char("It is empty.\r\n", ch); else { if (GET_OBJ_VAL(obj,0) <= 0 || GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0)) { sprintf(buf, "Its contents seem somewhat murky.\r\n"); /* BUG */ } else { amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0); sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2); sprintf(buf, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2); } send_to_char(buf, ch); } } } } char *find_exdesc(char *word, struct extra_descr_data *list) { struct extra_descr_data *i; for (i = list; i; i = i->next) if (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 <angus@EDGIL.CCMAIL.COMPUSERVE.COM> for the * suggested fix to this problem. */ void look_at_target(Creature ch, char *arg) { int bits, found = FALSE, j, fnum, i = 0; Creature found_char = NULL; Object obj, found_obj = NULL; char *desc; if (!ch->desc) return; if (!*arg) { send_to_char("Look at what?\r\n", ch); 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, TRUE, FALSE); 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("Look at what?\r\n", ch); return; } /* 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(desc, ch); found = TRUE; } } /* 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(desc, ch); found = TRUE; } /* Does the argument match an extra desc of an object in the room? */ for (obj = world[ch->in_room].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(desc, ch); found = TRUE; } /* If an object was found back in generic_find */ if (bits) { if (!found) show_obj_to_char(found_obj, ch, 5); /* Show no-description */ else show_obj_to_char(found_obj, ch, 6); /* Find hum, glow etc */ } else if (!found) send_to_char("You do not see that here.\r\n", ch); } ACMD(do_look) { char arg2[MAX_INPUT_LENGTH]; int look_type; if (!ch->desc) return; if (GET_POS(ch) < POS_SLEEPING) send_to_char("You can't see anything but stars!\r\n", ch); else if (AFF_FLAGGED(ch, AFF_BLIND)) send_to_char("You can't see a damned thing, you're blind!\r\n", ch); else if (!CAN_SEE_IN_DARK_ROOM(ch, ch->in_room) && (IS_COMPLETE(ch->in_room) || ALWAYS_CLOSED(ch->in_room)) && (SECT(ch->in_room) == SECT_BUILDING || SECT(ch->in_room) == SECT_MONUMENT_CLOSED || SECT(ch->in_room) == SECT_MULTI || SECT(ch->in_room) == SECT_INSIDE)) { send_to_char("It is pitch black...\r\n", ch); list_char_to_char(world[ch->in_room].people, ch); /* glowing red eyes */ } else { half_chop(argument, arg, arg2); if (!*arg) /* "look" alone, without an argument at all */ look_at_room(ch); else if (is_abbrev(arg, "in")) look_in_obj(ch, arg2); /* did the char type 'look <direction>?' */ else if ((look_type = parse_direction(arg)) >= 0) look_in_direction(ch, look_type); else if (is_abbrev(arg, "at")) look_at_target(ch, arg2); else look_at_target(ch, arg); } } ACMD(do_examine) { Creature tmp_char; Object tmp_object; one_argument(argument, arg); if (!*arg) { send_to_char("Examine what?\r\n", ch); return; } look_at_target(ch, arg); 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_CONTAINER) || (GET_OBJ_TYPE(tmp_object) == ITEM_CORPSE) || (GET_OBJ_TYPE(tmp_object) == ITEM_CART)) { send_to_char("When you look inside, you see:\r\n", ch); look_in_obj(ch, arg); } } } void display_score_to_char(Creature ch, Creature to) { struct time_info_data *real_time_passed(time_t t2, time_t t1); extern const char *materials[]; extern struct discipline_data path[]; int i, j, c; struct time_info_data playing_time; msg_to_char(to, " +------------------------------ EmpireMUD AD --------------------------------+\r\n"); msg_to_char(to, " Name: %-18.18s", PERS(ch, ch, 1)); if (real_empire(GET_LOYALTY(ch)) != -1) msg_to_char(to, " Rank: %s\r\n", empire[real_empire(GET_LOYALTY(ch))].rank[GET_RANK(ch)-1]); else msg_to_char(to, "\r\n"); sprintf(buf, "%d point%s", GET_EXPERIENCE(ch), GET_EXPERIENCE(ch) != 1 ? "s" : ""); playing_time = *real_time_passed((time(0) - ch->player.time.logon) + ch->player.time.played, 0); sprintf(buf1, "%dd, %dh", playing_time.day, playing_time.hours); if (IS_WEREWOLF(ch)) sprintf(buf2, "Breed: %s", breed[(int) GET_BREED(ch)]); else *buf2 = '\0'; msg_to_char(to, " Experience: %-12.12s Play Time: %-13.13s %s\r\n", buf, buf1, buf2); if (IS_VAMPIRE(ch) && GET_REAL_AGE(ch) > GET_AGE(ch)) sprintf(buf, "%d/%d years", GET_AGE(ch), GET_REAL_AGE(ch)); else sprintf(buf, "%d years", GET_AGE(ch)); msg_to_char(to, " Age: %-20.20s", buf); if (IS_VAMPIRE(ch)) msg_to_char(to, "Clan: %-18.18s Generation: %d\r\n", clan[(int) GET_CLAN(ch)].name, GET_GENERATION(ch)); else if (IS_WEREWOLF(ch)) msg_to_char(to, "Tribe: %-17.17s Auspice: %s\r\n", tribe[(int) GET_TRIBE(ch)].name, auspice[(int) GET_AUSPICE(ch)]); else if (IS_GHOUL(ch)) msg_to_char(to, "Status: Ghoul\r\n"); else msg_to_char(to, "\r\n"); msg_to_char(to, " +------------------------------- Attributes ---------------------------------+\r\n"); display_attributes(ch, to, FALSE); msg_to_char(to, "+------------------------------- Abilities ----------------------------------+\r\n"); display_abilities(ch, to); if (IS_VAMPIRE(ch) || IS_GHOUL(ch)) { *buf = '\0'; for (i = 0, c = 0; i < NUM_DISCS; i++) if (GET_DISC(ch, i) > 0) { sprintf(buf + strlen(buf), " %-14.14s", disc[i].name); for (j = 1; j <= 10; j++) { if (GET_DISC(ch, i) >= j) strcat(buf, "*"); else strcat(buf, " "); } if (!(++c % 3)) strcat(buf, "\r\n "); } if (c % 3) strcat(buf, "\r\n "); if (*buf) { msg_to_char(to, "+------------------------------- Disciplines --------------------------------+\r\n "); msg_to_char(to, buf); } if (GET_THAUMATURGY(ch)) { *buf = '\0'; for (i = 0, c = 0; i < NUM_PATHS; i++) if (GET_PATH(ch, i) > 0) { sprintf(buf + strlen(buf), " %-19.19s", path[i].name); for (j = 1; j <= 5; j++) { if (GET_PATH(ch, i) >= j) strcat(buf, "*"); else strcat(buf, " "); } if (!(++c % 3)) strcat(buf, "\r\n "); } if (c % 3) strcat(buf, "\r\n "); if (*buf) { msg_to_char(to, "+---------------------------------- Paths ----------------------------------+\r\n "); msg_to_char(to, buf); } } } msg_to_char(to, "+----------------------------------------------------------------------------+\r\n "); /* Willpower setup into buf */ sprintf(buf, "%-14.14s", "Willpower"); for (i = 0; i < 10; i++) if (GET_MAX_WILLPOWER(ch) > i) strcat(buf, "*"); else strcat(buf, " "); /* Humanity setup into buf1 */ sprintf(buf1, "%-14.14s", "Humanity"); for (i = 0; i < 10; i++) if (GET_HUMANITY(ch) > i) strcat(buf1, "*"); else strcat(buf1, " "); /* Current Willpower setup into buf2 */ sprintf(buf2, "%-15.15s", ""); for (i = 0; i < 10; i++) if (GET_WILLPOWER(ch) > i) strcat(buf2, "o"); else strcat(buf2, " "); /* These are displayed a little different for vampires */ if (IS_VAMPIRE(ch)) { /* Line 1: 2 place-holders, then Willpower, leave the third column for now.. */ msg_to_char(to, " %-14.14s%-10.10s %s ", "", "", buf); msg_to_char(to, "%-14.14s", "Conscience"); for (i = 0; i < 10; i++) if (GET_CONSCIENCE(ch) > i) msg_to_char(to, "*"); else msg_to_char(to, " "); msg_to_char(to, "\r\n"); /* Line 2: 2 place-holders, Current Willpower, leave third column */ msg_to_char(to, " %-14.14s%-10.10s %s ", "", "", buf2); msg_to_char(to, "%-14.14s", "Self-Control"); for (i = 0; i < 10; i++) if (GET_SELF_CONTROL(ch) > i) msg_to_char(to, "*"); else msg_to_char(to, " "); msg_to_char(to, "\r\n"); /* Line 3: 2 place-holders, Humanity, leave third column */ msg_to_char(to, " %-14.14s%-10.10s %s ", "", "", buf1); msg_to_char(to, "%-14.14s", "Courage"); for (i = 0; i < 10; i++) if (GET_COURAGE(ch) > i) msg_to_char(to, "*"); else msg_to_char(to, " "); msg_to_char(to, "\r\n"); } else { msg_to_char(to, " %s %s\r\n", buf, buf1); msg_to_char(to, " %s\r\n", buf2); } /* Gods and Immortals: */ if (IS_GOD(ch) || IS_IMMORTAL(ch)) { *buf = '\0'; for (i = 0, j = 0; i < NUM_ITEM_MATS; i++) if (GET_RESOURCE(ch, i)) sprintf(buf + strlen(buf), " %-14.14s %-6d%s", materials[i], GET_RESOURCE(ch, i), !(++j % 3) ? "\r\n" : " "); if (j % 3) strcat(buf, "\r\n"); if (*buf) msg_to_char(to, " +------------------------------- Resources ----------------------------------+\r\n%s", buf); } } ACMD(do_score) { Creature victim; if (REAL_NPC(ch)) return; one_argument(argument, arg); if (IS_IMMORTAL(ch) && *arg) { if (!(victim = get_char_vis(ch, arg, FIND_CHAR_WORLD))) msg_to_char(ch, NOPERSON); else if (IS_NPC(victim)) msg_to_char(ch, "You can't get a score sheet for an NPC.\r\n"); else if (GET_REAL_LEVEL(victim) > GET_REAL_LEVEL(ch)) msg_to_char(ch, "You can't get a score sheet for someone of a higher level!\r\n"); else display_score_to_char(victim, ch); return; } display_score_to_char(ch, ch); } /* Form is like affects only designed to tell you the name of your shape */ ACMD(do_form) { /* See What form you are in */ if(GET_MORPH(ch) == MORPH_NONE){ msg_to_char(ch, "You are currently in homid form.\r\n"); } else if(GET_MORPH(ch) == MORPH_GLABRO){ msg_to_char(ch, "You are currently in glabro form.\r\n"); } else if(GET_MORPH(ch) == MORPH_CRINOS){ msg_to_char(ch, "You are currently in crino form.\r\n"); } else if(GET_MORPH(ch) == MORPH_HISPO){ msg_to_char(ch, "You are currently in hispo form.\r\n"); } else if(GET_MORPH(ch) == MORPH_LUPUS){ msg_to_char(ch, "You are currently in lupus form.\r\n"); } else { /* This should never be seen */ msg_to_char(ch, "You should never see this message, please report it to the admin!\r\n"); } } ACMD(do_affects) { int i; if (IS_NPC(ch)) return; msg_to_char(ch, " Affects:\r\n"); /* Conditions */ /* This reports conditions all on one line. */ sprintf(buf1, " You are "); if (GET_COND(ch, FULL) >= 420) strcat(buf1, "hungry, "); if (GET_COND(ch, THIRST) >= 345) strcat(buf1, "thirsty, "); if (GET_COND(ch, DRUNK) > 150) strcat(buf1, "inebriated, "); if (GET_COND(ch, TIRED) >= 345) strcat(buf1, "exhausted, "); if (strlen(buf1) > 13) { /* We have a condition */ buf1[strlen(buf1)-2] = '\0'; /* This removes the final ", " */ for (i = strlen(buf1); i >= 0; i--) if (buf1[i] == ',') { /* Looking for that last ',' */ strcpy(buf2, buf1 + i + 1); sprintf(buf1 + i, " and%s", buf2); break; } msg_to_char(ch, "%s.\r\n", buf1); } /* Morph */ if (GET_MORPH(ch) != MORPH_NONE) msg_to_char(ch, " You are in the form of %s!\r\n", morph_string(ch, MORPH_STRING_NAME)); /* * Other Affects * I've decided it's unrealistic to list all affects.. how would you know * how many hours of a charm you have left? How do you know it's really * even still active until you try to use it? */ if (AFF_FLAGGED(ch, AFF_BLIND)) msg_to_char(ch, " You have been blinded!\r\n"); if (AFF_FLAGGED(ch, AFF_CHARM)) msg_to_char(ch, " You have been charmed!\r\n"); if (HAS_INFRA(ch)) msg_to_char(ch, " Your eyes glow red.\r\n"); if (AFF_FLAGGED(ch, AFF_INVISIBLE)) msg_to_char(ch, " You're invisible!\r\n"); if (DSC_FLAGGED(ch, DSC_HEIGHTENED_SENSES)) msg_to_char(ch, " Your perceptions are heightened.\r\n"); if (DSC_FLAGGED(ch, DSC_UNSEEN_PRESENCE)) msg_to_char(ch, " You are walking through the shadows, out of sight!\r\n"); if (DSC_FLAGGED(ch, DSC_CANT_SPEND_WILLPOWER)) msg_to_char(ch, " Your Beast is cowering in the depths of your mind!\r\n"); if (DSC_FLAGGED(ch, DSC_TALONS_OF_THE_BEAST)) msg_to_char(ch, " Your fingers are bent into hideous talons!\r\n"); if (DSC_FLAGGED(ch, DSC_EARTHMELD)) msg_to_char(ch, " You are interred within the earth!\r\n"); if (DSC_FLAGGED(ch, DSC_AWE)) msg_to_char(ch, " You have a supernatural aura of desire!\r\n"); if (DSC_FLAGGED(ch, DSC_ENTRANCEMENT)) msg_to_char(ch, " You have been entranced!\r\n"); if (DSC_FLAGGED(ch, DSC_MAJESTY)) msg_to_char(ch, " You have a majestic aura about you!\r\n"); if (DSC_FLAGGED(ch, DSC_TONGUE_OF_THE_ASP)) msg_to_char(ch, " Your tongue is long and forked!\r\n"); if (DSC_FLAGGED(ch, DSC_BITUMENOUS_FLESH)) msg_to_char(ch, " You are mummified in hardened flesh!\r\n"); if (DSC_FLAGGED(ch, DSC_ARMOR_OF_VITALITY)) msg_to_char(ch, " Your flesh is as hard as marble!\r\n"); if (DSC_FLAGGED(ch, DSC_MASK)) msg_to_char(ch, " Your Cainite appearance is masked!\r\n"); if (DSC_FLAGGED(ch, DSC_SOUL_MASK)) msg_to_char(ch, " Your aura is masked!\r\n"); } ACMD(do_inventory) { void inventory_store_building(Creature ch); send_to_char("You are carrying:\r\n", ch); list_obj_to_char(ch->carrying, ch, 1, TRUE); if (STORE_BUILDING(ch->in_room) && CAN_USE_ROOM(ch, ch->in_room, 0)) inventory_store_building(ch); } ACMD(do_equipment) { int i, found = 0; send_to_char("You are using:\r\n", ch); for (i = 0; i < NUM_WEARS; i++) { if (GET_EQ(ch, i)) { if (CAN_SEE_OBJ(ch, GET_EQ(ch, i))) { send_to_char(where[i], ch); show_obj_to_char(GET_EQ(ch, i), ch, 1); found = TRUE; } else { send_to_char(where[i], ch); send_to_char("Something.\r\n", ch); found = TRUE; } } } if (!found) send_to_char(" Nothing.\r\n", ch); } ACMD(do_time) { extern const char *weekdays[]; extern struct time_info_data time_info; const char *suf; int weekday, day; sprintf(buf, "It is %d o'clock %s, on ", ((time_info.hours % 12 == 0) ? 12 : ((time_info.hours) % 12)), ((time_info.hours >= 12) ? "pm" : "am")); /* 30 days in a month */ weekday = ((30 * time_info.month) + time_info.day + 1) % 7; strcat(buf, weekdays[weekday]); strcat(buf, "\r\n"); send_to_char(buf, ch); day = time_info.day + 1; /* day in [1..30] */ /* 11, 12, and 13 are the infernal exceptions to the rule */ if ((day % 10) == 1 && day != 11) suf = "st"; else if ((day % 10) == 2 && day != 12) suf = "nd"; else if ((day % 10) == 3 && day != 13) suf = "rd"; else suf = "th"; msg_to_char(ch, "The %d%s day of the month of %s, year %d.\r\n", day, suf, month_name[(int) time_info.month], time_info.year); } ACMD(do_help) { extern char *help; extern struct help_index_element *help_table; extern int top_of_helpt; int chk, bot, top, mid, minlen; if (!ch->desc) return; skip_spaces(&argument); if (!*argument) { page_string(ch->desc, help, 0); return; } if (!help_table) { send_to_char("No help available.\r\n", ch); return; } bot = 0; top = top_of_helpt; minlen = strlen(argument); for (;;) { mid = (bot + top) / 2; if (bot > top) { send_to_char("There is no help on that word.\r\n", ch); return; } else if (!(chk = strn_cmp(argument, help_table[mid].keyword, minlen))) { /* trace backwards to find first matching entry. Thanks Jeff Fink! */ while ((mid > 0) && (!(chk = strn_cmp(argument, help_table[mid - 1].keyword, minlen)))) mid--; if (GET_LEVEL(ch) < help_table[mid].level) msg_to_char(ch, "There is no help on that word.\r\n"); else page_string(ch->desc, help_table[mid].entry, 0); return; } else { if (chk > 0) bot = mid + 1; else top = mid - 1; } } } /* Estimates length of all color codes in a string */ int count_amp(char *string) { int i, t; for (i = 0, t = 0; i < strlen(string); i++) if (string[i] == '&' || string[i] == '\r') t += 2; return t; } /* centers 1 line of text (may crash with long lines, use center_full_text) */ char *center_text(char *input) { static char output[MAX_STRING_LENGTH]; int s, t; *output = '\0'; s = (78 - (strlen(input)-count_amp(input))) / 2; if (s >= 1) for (t = 1; t <= s; t++) strcat(output, " "); strcat(output, input); return output; } /* centers a long line of text (please don't include linebreaks) */ char *center_full_text(char *input) { static char out[MAX_STRING_LENGTH]; char buffer[MAX_INPUT_LENGTH], buffer1[MAX_INPUT_LENGTH], buffer2[MAX_INPUT_LENGTH]; *buffer = *buffer1 = *buffer2 = '\0'; strcpy(buffer, input); if (strlen(input) > 80) { strcpy(buffer1, buffer + 78); sprintf(buffer + 78, "\r\n"); if (strlen(buffer1) > 80) { strcpy(buffer2, buffer1 + 78); sprintf(buffer1 + 78, "\r\n"); } } sprintf(out, "%s", center_text(buffer)); if (*buffer1) strcat(out, center_text(buffer1)); if (*buffer2) strcat(out, center_text(buffer2)); return out; } char *perform_immort_who(Creature ch, char *name_search, int low, int high, int empire_who, int rp, int mode) { static char who_output[MAX_STRING_LENGTH]; Creature tch; Descr d; /* who_output is our final message */ *who_output = '\0'; /* buf1 will store our string of who's */ *buf1 = '\0'; for (d = descriptor_list; d; d = d->next) { if (STATE(d) != CON_PLAYING) continue; if (d->original) tch = d->original; else if (!(tch = d->character)) continue; if (*name_search && !is_abbrev(name_search, PERS(tch, tch, 1)) && !strstr(GET_TITLE(tch), name_search)) continue; if (!CAN_SEE_NO_DARK(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high) continue; if (!IS_IMMORTAL(tch) && !mode) continue; if (!IS_GOD(tch) && mode) continue; if (empire_who && real_empire(GET_LOYALTY(ch)) != real_empire(GET_LOYALTY(tch))) continue; if (rp && !PRF_FLAGGED(tch, PRF_RP)) continue; /* Initialize the buffer */ *buf = '\0'; if (real_empire(GET_LOYALTY(tch)) != -1) sprintf(buf + strlen(buf), "<%s&0> ", empire[real_empire(GET_LOYALTY(tch))].rank[GET_RANK(tch)-1]); sprintf(buf + strlen(buf), "%s%s&0", PERS(tch, tch, 1), GET_TITLE(tch)); if (IS_AFK(tch)) strcat(buf, " &1[AFK]&0"); if ((tch->char_specials.timer * SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN) >= 5) sprintf(buf, "%s (idle: %d)", buf, (tch->char_specials.timer * SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN)); if (PRF_FLAGGED(tch, PRF_RP)) strcat(buf, " &5[RP]&0"); if (GET_INVIS_LEV(tch)) sprintf(buf + strlen(buf), " (i%d)", GET_INVIS_LEV(tch)); else if (AFF_FLAGGED(tch, AFF_INVISIBLE)) sprintf(buf + strlen(buf), " (invis)"); if (PLR_FLAGGED(tch, PLR_MAILING)) strcat(buf, " &6(mailing)&0"); else if (PLR_FLAGGED(tch, PLR_WRITING)) strcat(buf, " &6(writing)&0"); if (PRF_FLAGGED(tch, PRF_DEAF)) strcat(buf, " (deaf)"); if (PRF_FLAGGED(tch, PRF_NOTELL)) strcat(buf, " (notell)"); if (PRF_FLAGGED(tch, PRF_NOOOC)) strcat(buf, " (!ooc)"); if (PRF_FLAGGED(tch, PRF_NOGOSS)) strcat(buf, " (!gos)"); strcat(buf1, strcat(buf, "&0\r\n")); } if (*buf1) { if (mode) strcpy(buf, "Gods"); else strcpy(buf, "Administrators"); strcat(buf, "\r\n"); if (mode) strcat(buf, "----"); else strcat(buf, "--------------"); sprintf(who_output, "\r\n%s\r\n%s", buf, buf1); } return (who_output); } char *perform_mort_who(Creature ch, char *name_search, int low, int high, int empire_who, int rp) { static char who_output[MAX_STRING_LENGTH]; Creature tch; Descr d; /* who_output is our final message */ *who_output = '\0'; /* buf1 will store our string of who's */ *buf1 = '\0'; for (d = descriptor_list; d; d = d->next) { if (STATE(d) != CON_PLAYING) continue; if (d->original) tch = d->original; else if (!(tch = d->character)) continue; if (*name_search && !is_abbrev(name_search, PERS(tch, tch, 1)) && !strstr(GET_TITLE(tch), name_search)) continue; if (!CAN_SEE_NO_DARK(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high) continue; if (IS_IMMORTAL(tch) || IS_GOD(tch)) continue; if (empire_who && real_empire(GET_LOYALTY(ch)) != real_empire(GET_LOYALTY(tch))) continue; if (rp && !PRF_FLAGGED(tch, PRF_RP)) continue; /* Initialize the buffer */ *buf = '\0'; if (real_empire(GET_LOYALTY(tch)) != -1) sprintf(buf + strlen(buf), "<%s&0> ", empire[real_empire(GET_LOYALTY(tch))].rank[GET_RANK(tch)-1]); sprintf(buf + strlen(buf), "%s%s&0", PERS(tch, tch, 1), GET_TITLE(tch)); if (IS_AFK(tch)) strcat(buf, " &1[AFK]&0"); if ((tch->char_specials.timer * SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN) >= 5) sprintf(buf, "%s (idle: %d)", buf, (tch->char_specials.timer * SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN)); if (PRF_FLAGGED(tch, PRF_RP)) strcat(buf, " &5[RP]&0"); if (GET_INVIS_LEV(tch)) sprintf(buf + strlen(buf), " (i%d)", GET_INVIS_LEV(tch)); else if (AFF_FLAGGED(tch, AFF_INVISIBLE)) sprintf(buf + strlen(buf), " (invis)"); if (PLR_FLAGGED(tch, PLR_MAILING)) strcat(buf, " &6(mailing)&0"); else if (PLR_FLAGGED(tch, PLR_WRITING)) strcat(buf, " &6(writing)&0"); if (PRF_FLAGGED(tch, PRF_DEAF)) strcat(buf, " (deaf)"); if (PRF_FLAGGED(tch, PRF_NOTELL)) strcat(buf, " (notell)"); if (PRF_FLAGGED(tch, PRF_NOOOC)) strcat(buf, " (!ooc)"); if (PRF_FLAGGED(tch, PRF_NOGOSS)) strcat(buf, " (!gos)"); strcat(buf1, strcat(buf, "&0\r\n")); } if (*buf1) { strcpy(buf, "Mortals\r\n-------"); sprintf(who_output, "\r\n%s\r\n%s", buf, buf1); } return (who_output); } #define WHO_FORMAT \ "format: who [minlev[-maxlev]] [-n name] [-o] [-e] [-r]\r\n" ACMD(do_who) { char name_search[MAX_INPUT_LENGTH], output[MAX_STRING_LENGTH], part[MAX_STRING_LENGTH]; char mode; int low = 0, high = LVL_IMPL; int rp = 0, empire_who = 0; skip_spaces(&argument); strcpy(buf, argument); name_search[0] = '\0'; while (*buf) { half_chop(buf, arg, buf1); if (isdigit(*arg)) { sscanf(arg, "%d-%d", &low, &high); strcpy(buf, buf1); } else if (*arg == '-') { mode = *(arg + 1); /* just in case; we destroy arg in the switch */ switch (mode) { case 'r': rp = 1; strcpy(buf, buf1); break; case 'l': half_chop(buf1, arg, buf); sscanf(arg, "%d-%d", &low, &high); break; case 'n': half_chop(buf1, name_search, buf); break; case 'e': empire_who = 1; strcpy(buf, buf1); break; default: send_to_char(WHO_FORMAT, ch); return; } /* end of switch */ } else { /* endif */ send_to_char(WHO_FORMAT, ch); return; } } /* end while (parser) */ *output = '\0'; /* Immortals first */ strcat(output, perform_immort_who(ch, name_search, low, high, empire_who, rp, 0)); /* Gods second */ strcpy(part, perform_immort_who(ch, name_search, low, high, empire_who, rp, 1)); if (*part) strcat(output, part); /* Then mortals */ strcpy(part, perform_mort_who(ch, name_search, low, high, empire_who, rp)); if (*part) strcat(output, part); if (*output) page_string(ch->desc, output, 1); else /* Didn't find a match to set parameters */ msg_to_char(ch, "You don't see anyone like that.\r\n"); } void users_output(Creature to, Creature tch, Descr d, char *name_search, int low, int high, int rp) { extern const char *connected_types[]; Creature ch = tch; char levelname[20], *timeptr, idletime[10]; char line[200], line2[220], state[30]; const char *format = "%3d %s %-13s %-15s %-3s %-8s "; if (!ch && STATE(d) == CON_PLAYING) { if (d->original) ch = d->original; else if (!(ch = d->character)) return; } if (ch) { if (*name_search && !is_abbrev(name_search, GET_NAME(ch))) return; if (!CAN_SEE(to, ch) || GET_LEVEL(ch) < low || GET_LEVEL(ch) > high) return; if (rp && !PRF_FLAGGED(ch, PRF_RP)) return; if (GET_INVIS_LEV(ch) > GET_LEVEL(to)) return; sprintf(levelname, "%d", GET_LEVEL(ch)); } else strcpy(levelname, "-"); if (d) { timeptr = asctime(localtime(&d->login_time)); timeptr += 11; *(timeptr + 8) = '\0'; } else timeptr = str_dup(""); if (ch && d && ch == d->original) strcpy(state, "Switched"); else if (d) strcpy(state, connected_types[STATE(d)]); else strcpy(state, "Linkdead"); if (ch) sprintf(idletime, "%3d", ch->char_specials.timer * SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN); else strcpy(idletime, ""); sprintf(line, format, d ? d->desc_num : 0, levelname, (ch && ch->player.name) ? ch->player.name : (d && d->character && d->character->player.name) ? d->character->player.name : "UNDEFINED", state, idletime, timeptr); if (d && d->host && *d->host && (!ch || GET_LEVEL(ch) <= GET_LEVEL(to))) sprintf(line + strlen(line), "[%s]\r\n", d->host); else if (d) strcat(line, "[Hostname unknown]\r\n"); else strcat(line, "\r\n"); if (!d) sprintf(line2, "&6%s&0", line); else if (STATE(d) != CON_PLAYING) sprintf(line2, "&2%s&0", line); else strcpy(line2, line); strcpy(line, line2); send_to_char(line, to); } #define USERS_FORMAT \ "format: users [-l minlevel[-maxlevel]] [-n name] [-h host] [-r] [-p]\r\n" ACMD(do_users) { char mode; char name_search[MAX_INPUT_LENGTH], host_search[MAX_INPUT_LENGTH]; Creature tch; Descr d; int low = 0, high = LVL_IMPL, num_can_see = 0; int rp = 0, playing = 0, deadweight = 0; host_search[0] = name_search[0] = '\0'; strcpy(buf, argument); while (*buf) { half_chop(buf, arg, buf1); if (*arg == '-') { mode = *(arg + 1); /* just in case; we destroy arg in the switch */ switch (mode) { case 'r': rp = 1; playing = 1; strcpy(buf, buf1); break; case 'p': playing = 1; strcpy(buf, buf1); break; case 'd': deadweight = 1; strcpy(buf, buf1); 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; default: send_to_char(USERS_FORMAT, ch); return; } /* end of switch */ } else { /* endif */ send_to_char(USERS_FORMAT, ch); return; } } /* end while (parser) */ msg_to_char(ch, "Num L Name State Idl Login@ Site\r\n"); msg_to_char(ch, "--- - ------------- --------------- --- -------- ------------------------\r\n"); one_argument(argument, arg); if (!*host_search) for (tch = character_list; tch; tch = tch->next) { if (IS_NPC(tch) || tch->desc) continue; users_output(ch, tch, NULL, name_search, low, high, rp); num_can_see++; } for (d = descriptor_list; d; d = d->next) { if (STATE(d) != CON_PLAYING && playing) continue; if (STATE(d) == CON_PLAYING && deadweight) continue; if (*host_search && !strstr(d->host, host_search)) continue; users_output(ch, NULL, d, name_search, low, high, rp); num_can_see++; } msg_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) { extern char *credits; extern char *info; extern char *motd; extern char *imotd; extern char *wizlist; extern char *godlist; extern char *policies; extern char *handbook; extern const char *version; switch (subcmd) { case SCMD_CREDITS: page_string(ch->desc, credits, 0); break; case SCMD_INFO: page_string(ch->desc, info, 0); break; case SCMD_WIZLIST: page_string(ch->desc, wizlist, 0); break; case SCMD_GODLIST: page_string(ch->desc, godlist, 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("\033[H\033[J", ch); break; case SCMD_VERSION: send_to_char(strcat(strcpy(buf, version), "\r\n"), ch); break; default: log("SYSERR: Unhandled case in do_gen_ps. (%d)", subcmd); return; } } /* Basic distance */ #define distance(x, y, a, b) ((x - a) * (x - a) + (y - b) * (y - b)) void perform_mortal_where(Creature ch, char *arg) { register Creature i; register Descr d; if (!*arg) { send_to_char("Players near you\r\n--------------------\r\n", ch); 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 (i->in_room == NOWHERE || !CAN_SEE(ch, i)) continue; if (distance(X_COORD(ch->in_room), Y_COORD(ch->in_room), X_COORD(i->in_room), Y_COORD(i->in_room)) > distance(0, 0, 0, 50)) continue; if (AFF_FLAGGED(i, AFF_NO_SEE_IN_ROOM) || MORPH_FLAGGED(i, MORPH_FLAG_NPC)) continue; sprintf(buf, "%-20s - (%3d, %3d) %s\r\n", PERS(i, ch, 0), X_COORD(i->in_room), Y_COORD(i->in_room), get_room_name(i->in_room, 0)); send_to_char(buf, ch); } } else { /* print only FIRST char, not all. */ for (i = character_list; i; i = i->next) { if (i->in_room == NOWHERE || i == ch) continue; if (!CAN_SEE(ch, i)) continue; if (!isname(arg, i->player.name)) continue; if (distance(X_COORD(ch->in_room), Y_COORD(ch->in_room), X_COORD(i->in_room), Y_COORD(i->in_room)) > distance(0, 0, 0, 50)) continue; if (AFF_FLAGGED(i, AFF_NO_SEE_IN_ROOM) || MORPH_FLAGGED(i, MORPH_FLAG_NPC)) continue; sprintf(buf, "%-25s - (%3d, %3d) %s\r\n", PERS(i, ch, 0), X_COORD(i->in_room), Y_COORD(i->in_room), get_room_name(i->in_room, 0)); send_to_char(buf, ch); return; } send_to_char("No-one around by that name.\r\n", ch); } } void print_object_location(int num, Object obj, Creature ch, int recur) { if (num > 0) sprintf(buf, "O%3d. %-25s - ", num, GET_OBJ_DESC(obj, ch, 1)); else sprintf(buf, "%33s", " - "); if (obj->in_room > NOWHERE) { sprintf(buf + strlen(buf), "(%d, %d) %s\r\n", X_COORD(obj->in_room), Y_COORD(obj->in_room), get_room_name(obj->in_room, 0)); send_to_char(buf, ch); } else if (obj->carried_by) { sprintf(buf + strlen(buf), "carried by %s\r\n", PERS(obj->carried_by, ch, 1)); send_to_char(buf, ch); } else if (obj->worn_by) { sprintf(buf + strlen(buf), "worn by %s\r\n", PERS(obj->worn_by, ch, 1)); send_to_char(buf, ch); } else if (obj->in_obj) { sprintf(buf + strlen(buf), "inside %s%s\r\n", GET_OBJ_DESC(obj->in_obj, ch, 1), (recur ? ", which is" : " ")); send_to_char(buf, ch); if (recur) print_object_location(0, obj->in_obj, ch, recur); } else { sprintf(buf + strlen(buf), "in an unknown location\r\n"); send_to_char(buf, ch); } } void perform_immort_where(Creature ch, char *arg) { register Creature i; register Object k; Descr d; int num = 0, found = 0; if (!*arg) { send_to_char("Players\r\n-------\r\n", ch); for (d = descriptor_list; d; d = d->next) if (STATE(d) == CON_PLAYING) { i = (d->original ? d->original : d->character); if (i && CAN_SEE(ch, i) && (i->in_room != NOWHERE)) { if (d->original) sprintf(buf, "%-20s - (%3d, %3d) %s (in %s)\r\n", GET_NAME(i), X_COORD(d->character->in_room), Y_COORD(d->character->in_room), get_room_name(d->character->in_room, 0), GET_NAME(d->character)); else sprintf(buf, "%-20s - (%3d, %3d) %s\r\n", GET_NAME(i), X_COORD(i->in_room), Y_COORD(i->in_room), get_room_name(i->in_room, 0)); send_to_char(buf, ch); } } } else { for (i = character_list; i; i = i->next) if (CAN_SEE(ch, i) && i->in_room != NOWHERE && isname(arg, i->player.name)) { found = 1; sprintf(buf, "M%3d. %-25s - (%3d, %3d) %s\r\n", ++num, GET_NAME(i), X_COORD(i->in_room), Y_COORD(i->in_room), get_room_name(i->in_room, 0)); send_to_char(buf, ch); } 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("Couldn't find any such thing.\r\n", ch); } } ACMD(do_where) { one_argument(argument, arg); if (GET_LEVEL(ch) >= LVL_GOD) perform_immort_where(ch, arg); else perform_mortal_where(ch, arg); } ACMD(do_diagnose) { Creature vict; one_argument(argument, buf); if (*buf) { if (!(vict = get_char_vis(ch, buf, FIND_CHAR_ROOM))) send_to_char(NOPERSON, ch); else diag_char_to_char(vict, ch); } else { if (FIGHTING(ch)) diag_char_to_char(FIGHTING(ch), ch); else send_to_char("Diagnose whom?\r\n", ch); } } void list_lore_to_char(Creature ch, Creature to) { void clean_lore(Creature ch); extern struct time_info_data *mud_time_passed(time_t t2, time_t t1); extern char *get_name_by_id(long id); extern long load_time(); struct lore_data *lore; char daystring[MAX_INPUT_LENGTH]; struct time_info_data t; int e; long beginning_of_time = load_time(); msg_to_char(to, "%s's lore:\r\n", PERS(ch, ch, 1)); clean_lore(ch); for (lore = GET_LORE(ch); lore; lore = lore->next) { t = *mud_time_passed((time_t) beginning_of_time, (time_t) lore->date); strcpy(buf, month_name[((int) t.month >= 0 ? (int) t.month : (int) -t.month)]); if (!strncmp(buf, "the ", 4)) strcpy(buf1, buf + 4); else strcpy(buf1, buf); sprintf(daystring, "%d, %s, Year %d", (int) -t.day + 1, buf1, -t.year + YEAR_ADD * 2); switch (lore->type) { case LORE_FOUND_EMPIRE: if ((e = real_empire(lore->value)) != -1) msg_to_char(to, " Proudly founded %s%s&0 on %s.\r\n", empire[e].banner, empire[e].name, daystring); break; case LORE_JOIN_EMPIRE: if ((e = real_empire(lore->value)) != -1) msg_to_char(to, " Honorably accepted into %s%s&0 on %s.\r\n", empire[e].banner, empire[e].name, daystring); break; case LORE_DEFECT_EMPIRE: if ((e = real_empire(lore->value)) != -1) msg_to_char(to, " Defected from %s%s&0 on %s.\r\n", empire[e].banner, empire[e].name, daystring); break; case LORE_KICKED_EMPIRE: if ((e = real_empire(lore->value)) != -1) msg_to_char(to, " Dishonorably discharged from %s%s&0 on %s.\r\n", empire[e].banner, empire[e].name, daystring); break; case LORE_PLAYER_KILL: msg_to_char(to, " Killed %s in battle on %s.\r\n", get_name_by_id(lore->value) ? CAP(get_name_by_id(lore->value)) : "an unknown foe", daystring); break; case LORE_PLAYER_DEATH: msg_to_char(to, " Slain by %s in battle on %s.\r\n", get_name_by_id(lore->value) ? CAP(get_name_by_id(lore->value)) : "an unknown foe", daystring); break; case LORE_TOWER_DEATH: msg_to_char(to, " Killed by a guard tower on %s.\r\n", daystring); break; case LORE_DEATH: msg_to_char(to, " Died on %s.\r\n", daystring); break; case LORE_START_VAMPIRE: if (IS_VAMPIRE(to)) msg_to_char(to, " Embraced prior to %s.\r\n", daystring); break; case LORE_EMBRACE_VAMPIRE: if (IS_VAMPIRE(to)) msg_to_char(to, " Embraced by %s on %s.\r\n", get_name_by_id(lore->value) ? CAP(get_name_by_id(lore->value)) : "an unknown Cainite", daystring); break; case LORE_MAKE_VAMPIRE: if (IS_VAMPIRE(to)) msg_to_char(to, " Sired %s on %s.\r\n", get_name_by_id(lore->value) ? CAP(get_name_by_id(lore->value)) : "an unknown Cainite", daystring); break; case LORE_MAKE_GHOUL: if (IS_VAMPIRE(to) || to == ch) msg_to_char(to, " Made a ghoul by %s on %s.\r\n", get_name_by_id(lore->value) ? CAP(get_name_by_id(lore->value)) : "an unknown Cainite", daystring); break; case LORE_TORPOR: if (IS_VAMPIRE(to)) msg_to_char(to, " Entered into torpor on %s.\r\n", daystring); break; } } } void whois_display(Creature ch, Creature vict) { extern const char *level_names[][2]; int e; if (GET_EMAIL(vict) && (!PRF_FLAGGED(vict, PRF_HIDEEMAIL) || GET_LEVEL(ch) == LVL_TOP)) sprintf(buf1, "E-mail: %s\r\n", GET_EMAIL(vict)); else *buf1 = '\0'; if (IS_VAMPIRE(ch) && IS_VAMPIRE(vict) && GET_CLAN(vict) == GET_CLAN(ch) && GET_GENERATION(vict) >= GET_GENERATION(ch)) sprintf(buf2, "Clan: %s\r\n", clan[(int) GET_CLAN(vict)].name); else if (IS_WEREWOLF(ch) && IS_WEREWOLF(vict) && GET_TRIBE(vict) == GET_TRIBE(ch)) sprintf(buf2, "Tribe: %s\r\n", tribe[(int) GET_TRIBE(vict)].name); else *buf2 = '\0'; sprintf(buf, "%s%s&0\r\n" "Status: %s%s\r\n" "%s%s", PERS(vict, vict, 1), GET_TITLE(vict), level_names[(int) GET_LEVEL(vict)][1], IS_HARDCORE(vict) ? ", &1HARDCORE&0" : "", buf1, buf2); if ((e = real_empire(GET_LOYALTY(vict))) != -1) sprintf(buf + strlen(buf), "%s of %s%s&0\r\n" "Territory: %d, Members: %d\r\n", empire[e].rank[GET_RANK(vict)-1], empire[e].banner, empire[e].name, empire[e].territory, empire[e].members); msg_to_char(ch, buf); if (GET_LORE(vict)) list_lore_to_char(vict, ch); } ACMD(do_whois) { void read_lore(Creature ch); Creature victim = 0; struct char_file_u tmp_store; skip_spaces(&argument); if (!*argument) { send_to_char("Who is whom?\r\n", ch); return; } CREATE(victim, struct char_data, 1); clear_char(victim); if (load_char(argument, &tmp_store) > -1) { store_to_char(&tmp_store, victim); if (!PLR_FLAGGED(victim, PLR_DELETED)) { read_lore(victim); whois_display(ch, victim); } else send_to_char("There is no such player.\r\n", ch); } else send_to_char("There is no such player.\r\n", ch); free(victim); }