#include <stdio.h> #include <string.h> #include <ctype.h> #include "db.h" #include "config.h" #include "externs.h" #include "powers.h" static int num_builtin_exits(OBJ *loc) { int ctr = 0; if(*atr_get(loc, "NORTH")) ctr++; if(*atr_get(loc, "SOUTH")) ctr++; if(*atr_get(loc, "EAST")) ctr++; if(*atr_get(loc, "WEST")) ctr++; if(*atr_get(loc, "NORTHEAST")) ctr++; if(*atr_get(loc, "NORTHWEST")) ctr++; if(*atr_get(loc, "SOUTHEAST")) ctr++; if(*atr_get(loc, "SOUTHWEST")) ctr++; return(ctr); } char *pseudo_exit_name(OBJ *loc, char *atrname) { char buf[4096]; OBJ *link; int i; struct { char *atrname; char *name; } exits[] = { {"NORTH", "North <N>"}, {"SOUTH", "South <S>"}, {"EAST", "East <E>"}, {"WEST", "West <W>"}, {"NORTHEAST", "Northeast <NE>"}, {"SOUTHEAST", "Southeast <SE>"}, {"SOUTHWEST", "Southwest <SW>"}, {"NORTHWEST", "Northwest <NW>"}, {NULL, NULL} }; for(i = 0;exits[i].atrname;++i) if(!string_compare(exits[i].atrname, atrname)) break; if(!(exits[i].atrname)) return(""); if((link = match_dbref(atr_get(loc, atrname), TYPE_ROOM))) { if(my_is_color(atr_get(link, "COLOR"))) sprintf(buf, "|%s|%s", atr_get(link, "COLOR"), exits[i].name); else sprintf(buf, "|n|%s", exits[i].name); } else sprintf(buf, "|n|%s", exits[i].name); return(stack_string_alloc(buf, 0)); } static char *list_builtin_exits(OBJ *loc, int *ctr) { char buf[4096], buf2[4096]; *buf = '\0'; if(*atr_get(loc, "NORTH")) { strcpy(buf2, pseudo_exit_name(loc, "NORTH")); if(!(*ctr)++) strcpy(buf, buf2); else sprintf(buf+strlen(buf), " %s", buf2); } if(*atr_get(loc, "SOUTH")) { strcpy(buf2, pseudo_exit_name(loc, "SOUTH")); if(!(*ctr)++) strcpy(buf, buf2); else sprintf(buf+strlen(buf), " %s", buf2); } if(*atr_get(loc, "EAST")) { strcpy(buf2, pseudo_exit_name(loc, "EAST")); if(!(*ctr)++) strcpy(buf, buf2); else sprintf(buf+strlen(buf), " %s", buf2); } if(*atr_get(loc, "WEST")) { strcpy(buf2, pseudo_exit_name(loc, "WEST")); if(!(*ctr)++) strcpy(buf, buf2); else sprintf(buf+strlen(buf), " %s", buf2); } if(*atr_get(loc, "NORTHEAST")) { strcpy(buf2, pseudo_exit_name(loc, "NORTHEAST")); if(!(*ctr)++) strcpy(buf, buf2); else sprintf(buf+strlen(buf), " %s", buf2); } if(*atr_get(loc, "NORTHWEST")) { strcpy(buf2, pseudo_exit_name(loc, "NORTHWEST")); if(!(*ctr)++) strcpy(buf, buf2); else sprintf(buf+strlen(buf), " %s", buf2); } if(*atr_get(loc, "SOUTHEAST")) { strcpy(buf2, pseudo_exit_name(loc, "SOUTHEAST")); if(!(*ctr)++) strcpy(buf, buf2); else sprintf(buf+strlen(buf), " %s", buf2); } if(*atr_get(loc, "SOUTHWEST")) { strcpy(buf2, pseudo_exit_name(loc, "SOUTHWEST")); if(!(*ctr)++) strcpy(buf, buf2); else sprintf(buf+strlen(buf), " %s", buf2); } return(stack_string_alloc(buf, 0)); } static void look_exits(OBJ *player, OBJ *loc, char *exit_name) { OBJ *thing; char buff[4096]; int ctr = 0; for(thing = loc->exits;thing;thing = thing->next_exit) if(can_see(player, thing, !is_dark(loc))) ctr++; ctr += num_builtin_exits(loc); if(!ctr) { notify(player, "|+W|No obvious exits"); return; } notify(player, exit_name); ctr = 0; strcpy(buff, list_builtin_exits(loc, &ctr)); for(thing = loc->exits;thing;thing = thing->next_exit) if(can_see(player, thing, !is_dark(loc))) { if(!ctr++) strcpy(buff, name(thing)); else sprintf(buff+strlen(buff), " %s", name(thing)); } if(*buff) notify(player, buff); else /* Only get here if a room is set dark */ notify(player, "|+W|No obvious exits"); } static void look_contents(OBJ *player, OBJ *loc, char *contents_name) { OBJ *thing; int can_see_loc; int contents = 0; char *clr = "n"; char x_buf[256]; DDATA *d; /* Check to see if he can see the location */ can_see_loc = !is_dark(loc); /* Check to see if there is anything there */ for(thing = loc->contents;thing;thing = thing->next_con) if(can_see(player, thing, can_see_loc)) contents++; if(!contents) return; notify(player, contents_name); for(thing = loc->contents;thing;thing = thing->next_con) { if(!can_see(player, thing, can_see_loc)) continue; strcpy(x_buf, ""); if(my_is_color(atr_get(thing, "COLOR"))) clr = atr_get(thing, "COLOR"); else clr = "n"; if((d = is_idle(thing))) strcat(x_buf, tprintf("|+W| (%s)", time_format(now-d->last_time, 1))); notify(player, tprintf("%s|%s| %s%s", unparse_object(player, thing), clr, atr_get(thing, "CAPTION"), x_buf)); } } static void look_simple(OBJ *player, OBJ *thing) { char *str; char *clr = "n"; char x_buf[256]; DDATA *d; /* If it's not an exit or it's not set transparent */ if(Typeof(thing) != TYPE_EXIT || !(thing->flags & OPAQUE)) { strcpy(x_buf, ""); if(my_is_color(atr_get(thing, "COLOR"))) clr = atr_get(thing, "COLOR"); else clr = "n"; if(Typeof(thing) == TYPE_EXIT) notify(player, tprintf("%s|%s| %s", unparse_object(player, thing), clr, atr_get(thing, "CAPTION"))); else { if((d = is_idle(thing))) strcat(x_buf, tprintf("|+W| (%s)", time_format(now-d->last_time, 1))); notify(player,tprintf("%s|%s| %s%s", unparse_object(player, thing), clr, atr_get(thing, "CAPTION"), x_buf)); } if(Typeof(thing) == TYPE_PLAYER) str = "I'm descriptionless. Sorry."; else str = "What you see is beyond description."; did_it(player, thing, "DESC", str, "PLEAVE"); } if(Typeof(thing) == TYPE_EXIT && thing->flags & OPAQUE) { if(thing->link) { notify(player, tprintf("You peer through to %s...", name(thing->link))); did_it(player, thing->link, "DESC", "You see nothing on the other side.", "PDESC"); look_contents(player, thing->link, "|+W|Contents:"); } else notify(player, "It's too dark to see anything."); } } void look_room(OBJ *player, OBJ *loc) { char buf[4096]; char *clr = "n"; if(my_is_color(atr_get(loc, "COLOR"))) clr = atr_get(loc, "COLOR"); sprintf(buf, "%s|%s| %s", unparse_object(player, loc), clr, atr_get(loc, "CAPTION")); notify(player, buf); if(Typeof(loc) == TYPE_ROOM) { if(!(player->flags & PLAYER_TERSE)) did_it(player, loc, "DESC", NULL, "PDESC"); if(could_doit(player, loc, "LOCK")) did_it(player, loc, "SUCC", NULL, "PSUCC"); else did_it(player, loc, "FAIL", NULL, "PFAIL"); } look_contents(player, loc, "|+W|Contents:"); look_exits(player, loc, "|+W|Obvious exits:"); } void do_look_around(OBJ *player) { look_room(player, player->location); } void do_look_at(OBJ *player, char *arg1) { OBJ *thing; if(!*arg1) { look_room(player, player->location); return; } thing = match_object(player, arg1, NOTYPE); if(!thing) { notify(player, no_match(arg1)); return; } if(Typeof(thing) == TYPE_ROOM) look_room(player, thing); else look_simple(player, thing); } char *flag_description(OBJ *thing) { char buf[4096]; strcpy(buf, "|+B|Type:|n| "); switch(Typeof(thing)) { case TYPE_ROOM: strcat(buf, "Room"); break; case TYPE_EXIT: strcat(buf, "Exit"); break; case TYPE_THING: strcat(buf, "Thing"); break; case TYPE_PLAYER: strcat(buf, "Player"); break; } /* Print flags */ strcat(buf, " |+B|Flags:|n|"); if(thing->flags & PUPPET) strcat(buf," puppet"); if(thing->flags & DARK) strcat(buf," dark"); if(thing->flags & HAVEN) strcat(buf," haven"); if(thing->flags & VISIBLE) strcat(buf," visible"); if(thing->flags & OPAQUE) strcat(buf, (Typeof(thing) == TYPE_EXIT)?" transparent":" opaque"); if(thing->flags & INHERIT_POWERS) strcat(buf," inherit"); if(thing->flags & QUIET) strcat(buf," quiet"); if(is_connected_raw(thing)) strcat(buf," connected"); switch(Typeof(thing)) { case TYPE_PLAYER: if(thing->flags & PLAYER_SLAVE) strcat(buf," slave"); if(thing->flags & PLAYER_TERSE) strcat(buf," terse"); if(thing->flags & PLAYER_ANSI) strcat(buf," ansi"); if(thing->flags & PLAYER_MORTAL) strcat(buf," mortal"); if(thing->flags & PLAYER_NO_WALLS) strcat(buf," no_walls"); if(thing->flags & PLAYER_NO_COM) strcat(buf," no_com"); if(thing->flags & PLAYER_NO_ANN) strcat(buf," no_ann"); break; case TYPE_EXIT: if(thing->flags & EXIT_LIGHT) strcat(buf," light"); break; case TYPE_THING: if(thing->flags & THING_LIGHT) strcat(buf," light"); break; case TYPE_ROOM: if(thing->flags & ROOM_FLOATING) strcat(buf," floating"); break; } return(stack_string_alloc(buf, 0)); } void look_atr(OBJ *player, OBJ *thing, ATTR *attr) { char buf[4096]; OBJ *o; char *value; value = atr_get_a(thing, attr); sprintf(buf, "|+B|%s%s|+C|[|+W|%s|+C|]|+B|:|n| ", attr->name, (attr->flags&AF_FUNC)?"()":"", unparse_atr_flags(attr->flags)); if(attr->flags & AF_DATE) notify(player, tprintf("%s%s", buf, mktm(atol(value), "D", player))); else if(attr->flags & AF_LOCK) notify(player, tprintf("%s%s", buf, unprocess_lock(player, value))); else if(attr->flags & AF_DBREF) { if(!*value || !(o = find_object(atoi((value)+1)))) notify(player, tprintf("%s%s", buf, value)); else notify(player, tprintf("%s%s", buf, unparse_object(player, o))); } else notify(player, tprintf("%s%s", buf, value)); } static void look_atrs(OBJ *player, OBJ *thing) { ALIST *atr; for(atr = thing->attrlist;atr;atr = atr->next) if(can_see_atr(player, thing, atr->attr)) look_atr(player, thing, atr->attr); } static int check_builtin_attrs(OBJ *player, char *arg) { char *attr_name; OBJ *victim; if(!(attr_name = strchr(arg, '/'))) return(0); *attr_name++ = '\0'; if(!(victim = match_object(player, arg, NOTYPE))) return(0); if(!string_compare(attr_name, "name")) notify(player, tprintf("|+B|Name: %s", name(victim))); else if(!string_compare(attr_name, "flags")) notify(player, tprintf("|+B|Flags: |n|%s", unparse_flags(victim))); else if(!string_compare(attr_name, "location")) notify(player, tprintf("|+B|Location: %s", unparse_object(player, victim->location))); else if(!string_compare(attr_name, "link")) notify(player, tprintf("|+B|Link: %s", unparse_object(player, victim->link))); else if(!string_compare(attr_name, "owner")) notify(player, tprintf("|+B|Owner: %s", unparse_object(player, victim->owner))); else if(!string_compare(attr_name, "creator")) notify(player, tprintf("|+B|Creator: %s", unparse_object(player, victim->creator))); else if(!string_compare(attr_name, "modified")) { if(!victim->mod_time) notify(player, "|+B|Modified: |n|NEVER"); else notify(player, tprintf("|+B|Modified: |n|%s", mktm(victim->mod_time, "D", player))); } else if(!string_compare(attr_name, "created")) { if(!victim->create_time) notify(player, "|+B|Created: |n|NEVER"); else notify(player, tprintf("|+B|Created: |n|%s", mktm(victim->create_time, "D", player))); } else return(0); return(1); } void do_examine(OBJ *player, char *arg) { ATTR *attr; OBJ *thing; OBJ *what; int pos = 0; char buf[4096]; int objects; if(!*arg) thing = player->location; else { if(strchr(arg, '/')) { if(!parse_attrib(player, arg, &thing, &attr)) { if(!check_builtin_attrs(player, arg)) notify(player, "No match."); return; } if(!can_see_atr(player, thing, attr)) { notify(player, perm_denied()); return; } look_atr(player, thing, attr); return; } thing = match_object(player, arg, NOTYPE); if(!thing) { notify(player, no_match(arg)); return; } } if((!controls(player, thing, POW_EXAMINE) && !(thing->flags & VISIBLE))) { strcpy(buf, unparse_object(player, thing)); notify(player, tprintf("%s is owned by %s", buf, unparse_object(player, thing->owner))); return; } notify(player, unparse_object(player, thing)); if(*Desc(thing) && can_see_atr(player, thing, find_attr("Desc"))) notify(player, Desc(thing)); if(Typeof(thing) == TYPE_PLAYER) { strcpy(buf, " |+B|Quota-Left:|n| "); if(power(thing, POW_NOQUOTA)) strcat(buf, "INFINITE"); else { objects = owns_stuff(thing); if(atoi(atr_get(thing, "QUOTA"))-objects <= 0) strcat(buf, "NONE"); else sprintf(buf, "%d", atoi(atr_get(thing, "QUOTA"))-objects); } } notify(player, tprintf("|+B|Owner:|n| %s |+B|%s:|n| %ld", name(thing->owner), config.currency_plural, Pennies(thing))); notify(player, flag_description(thing)); notify(player, tprintf("|+B|Created:|n| %s by %s", mktm(thing->create_time, "D", player), unparse_object(player, thing->creator))); notify(player, tprintf("|+B|Modified:|n| %s", (thing->mod_time > 0)?mktm(thing->mod_time, "D", player):"never")); look_atrs(player, thing); look_contents(player, thing, "|+W|Contents:"); switch(Typeof(thing)) { case TYPE_ROOM: for(what = exit_list;what;what = what->next) if(what->link && what->link == thing) { if(!pos) { notify(player, "|+W|Entrances:"); pos = 1; } notify(player, unparse_object(player, what)); } if(!pos) notify(player, "No entrances."); if(thing->exits) { notify(player, "|+W|Exits:"); for(what = thing->exits;what;what = what->next_exit) notify(player, unparse_object(player, what)); } else notify(player, "No exits."); break; case TYPE_THING: case TYPE_PLAYER: notify(player, tprintf( "|+B|Home:|n| %s", unparse_object(player, thing->link))); if(controls(player, thing->location, POW_EXAMINE) || controls(player, thing, POW_EXAMINE)) { notify(player, tprintf( "|+B|Location:|n| %s", unparse_object(player, thing->location))); } break; case TYPE_EXIT: notify(player, tprintf("|+B|Source:|n| %s", unparse_object(player, thing->location))); if(thing->link) notify(player, tprintf("|+B|Destination:|n| %s", unparse_object(player, thing->link))); break; } } void do_find(OBJ *player, char *arg) { OBJ *o; int ctr = 0; if(!*arg) { notify(player, "Find what?"); return; } for(o = player_list;o;o = o->next) if(string_match(o->name, arg)) if(controls(player, o->owner, POW_EXAMINE)) { notify(player, unparse_object(player, o)); ctr++; } for(o = thing_list;o;o = o->next) if(string_match(o->name, arg)) if(controls(player, o->owner, POW_EXAMINE)) { notify(player, unparse_object(player, o)); ctr++; } for(o = room_list;o;o = o->next) if(string_match(o->name, arg)) if(controls(player, o->owner, POW_EXAMINE)) { notify(player, unparse_object(player, o)); ctr++; } if(ctr) notify(player, tprintf("|+C|%d |+B|match%s found.", ctr, check_plural(ctr, "", "es"))); else notify(player, "No matches were found."); } void do_whereis(OBJ *player, char *arg) { OBJ *thing; if(!*arg) { notify(player, "Where is who?"); return; } thing = match_object(player, arg, NOTYPE); if(!thing) { if(!(thing = match_player(NULL, arg))) { notify(player, no_match(arg)); return; } } if(thing->owner == player) { notify(player, tprintf("%s is at %s.", unparse_object(player, thing), unparse_object(player, thing->location))); return; } if(Typeof(thing) == TYPE_PLAYER && thing->flags & DARK) { notify(player, tprintf("%s wishes to have some privacy.", name(thing))); if(!controls(player, thing, POW_EXAMINE)) { notify(thing, tprintf("%s tried to locate you and failed.", unparse_object(thing, player))); return; } notify(player, tprintf("Too bad! You use your powers to find %s anyway...", name(thing))); } notify(player, tprintf("%s is at %s.", unparse_object(player, thing), unparse_object(player, thing->location))); notify(thing, tprintf("%s has just located your position.", unparse_object(thing, player))); } void do_laston(OBJ *player, char *arg) { char *attr; OBJ *thing; time_t tim1, tim2; char *p; /* Show a list of players */ if(!*arg) { FILE *fp; const char *filename = "laston.db"; char buf[256]; char part1[256]; char host[256]; int num_lines = 0, ctr = 0; int color = 0; char *clr_str; if((fp = fopen(filename, "r")) == NULL) { notify(player, "You must specify a valid player's name."); log_error(tprintf("Missing \"%s\" file for +laston!", filename)); return; } while(!feof(fp)) { fgets(buf, sizeof(buf), fp); num_lines++; } fclose(fp); if((fp = fopen(filename, "r")) == NULL) { notify(player, "You must specify a valid player's name."); log_error(tprintf("Missing \"%s\" file for +laston!", filename)); return; } while(++ctr < num_lines-15) fgets(buf, sizeof(buf), fp); notify(player, tprintf("|+B|.%s.", my_string("-", 77))); notify(player, tprintf("|+B|||+B|%s|+B||", my_center("Last Players Connected", 77))); notify(player, tprintf("|+B||%s|", my_string("-", 77))); notify(player, tprintf("|+B|||+W|%s|+B|||+W| TIME |+B|||+W|%s|+B||", my_center("NAME", 21), my_center("HOST", 28))); notify(player, tprintf("|+B||%s|--------------------------|%s|", my_string("-", 21), my_string("-", 28))); while(!feof(fp)) { if(color) { color = 0; clr_str = "|C|"; } else { color = 1; clr_str = "|+C|"; } buf[0] = '\0'; fgets(buf, 22, fp); if(strlen(buf) < 15) break; buf[strlen(buf)-1] = '\0'; p = &buf[strlen(buf)-1]; while(p != buf && *p == ' ') p--; *(p+1) = '\0'; strcpy(part1, buf); fgets(buf, sizeof(buf), fp); buf[strlen(buf)-1] = '\0'; p = &buf[strlen(buf)-1]; while(p != buf && *p != ' ') p--; strcpy(host, p+1); *p = '\0'; if(!power(player, POW_HOST)) strcpy(host, "???"); notify(player, tprintf("|+B|| %s%s|+B|| %s%s |+B|| %s%s|+B||", clr_str, my_ljust(part1, 20), clr_str, buf, clr_str, my_ljust(host, 27))); } notify(player, tprintf("|+B|`%s'", my_string("-", 77))); fclose(fp); return; } if(!(thing = match_player(NULL, arg))) { notify(player, no_match(arg)); return; } if(!could_doit(player, thing, "LHIDE") && !controls(player, thing, POW_EXAMINE) && player != thing) { notify(player, tprintf("%s is hidden from you.", name(thing))); return; } attr = atr_get(thing, "LASTCONN"); tim1 = atol(attr); if(!tim1) { notify(player, tprintf("%s has never logged on.", name(thing))); return; } notify(player, tprintf("%s |+B|was last logged on|+W|: |+C|%s", name(thing), mktm(tim1, "D", player))); attr = atr_get(thing, "LASTDISC"); tim2 = atol(attr); notify(player, tprintf("%s |+B|last logged off at|+W|: |+C|%s", name(thing), mktm(tim2, "D", player))); attr = atr_get(thing, "LASTSITE"); if(strlen(attr) && power(player, POW_HOST)) notify(player, tprintf("%s |+B|last connected from|+W|: |+C|%s", name(thing), attr)); if(tim2 < tim1) if(is_connected(player, thing)) notify(player, tprintf("%s is currently connected.", name(thing))); }