#include <stdio.h> #include <string.h> #include <ctype.h> #include "db.h" #include "externs.h" static void add_match(OBJ *obj, OBJ ***match_list) { int i; if(!*match_list) *match_list = (OBJ **)stack_alloc(sizeof(OBJ *), 0, 1); for(i = 0;(*match_list)[i];++i) if((*match_list)[i] == obj) return; *match_list = (OBJ **)stack_realloc_tmp(*match_list, sizeof(OBJ *)*(i+1)); (*match_list)[i] = obj; (*match_list)[i+1] = NULL; } OBJ *match_dbref(char *str, int type) { OBJ *o; if(*str != '#' || !*(str+1)) return(NULL); if((o = find_object(atoi(str+1)))) if(type & Typeof(o)) return(o); return(NULL); } OBJ *match_player(OBJ *player, char *str) { OBJ *o, *loc; char *p = str; if(player) { if(!string_compare(str, "me")) return(player); loc = player->location; } else loc = NULL; if(*str == '*') { loc = NULL; p++; } if(!*p) return(NULL); for(o = player_list;o;o = o->next) if(!loc || o->location == loc) if(!string_compare(p, o->name) || !string_compare(p, atr_get(o, "ALIAS"))) { return(o); } o = match_dbref(p, TYPE_PLAYER); return(o); } OBJ *match_contents(OBJ *thing, char *str, int type) { OBJ *o, **matches = NULL; if(!thing || !*str) return(NULL); for(o = thing->contents;o;o = o->next_con) if(Typeof(o) & type) { if(string_match(o->name, str)) add_match(o, &matches); if(type & TYPE_PLAYER) if(!string_compare(atr_get(o, "ALIAS"), str)) add_match(o, &matches); } if(!matches || !matches[0] || matches[1]) return(NULL); return(matches[0]); } static OBJ *match_exits(OBJ *room, char *str) { OBJ *o; char buf[1024]; char *p, *q, *r; if(!room || !*str) return(NULL); for(o = room->exits;o;o = o->next_exit) { if((p = strchr(o->name, '<'))) { if((r = strchr(p+1, '>'))) { q = p; while(isspace(q > o->name && *(--q))); /* Whole loop */ if(q > o->name) { strncpy(buf, o->name, q-o->name); *(buf+(q-o->name)) = '\0'; if(!string_compare(buf, str)) return(o); } p++; if(p-r) { strncpy(buf, p, r-p); *(buf+(r-p)) = '\0'; if(!string_compare(buf, str)) return(o); } } } if((p = strchr(o->name, EXIT_DELIMITER))) { if(!string_compare(p+1, str)) return(o); strncpy(buf, o->name, p-o->name); *(buf+(p-o->name)) = '\0'; } else strcpy(buf, o->name); if(!string_compare(buf, str)) return(o); } return(NULL); } OBJ *match_object(OBJ *player, char *str, int type) { OBJ *o; OBJ **matches = NULL; /* If it starts with a '#', they MUST be specifying a dbref number */ if(*str == '#') return(match_dbref(str, type)); if(player) { if(!string_compare(str, "me") && (Typeof(player) & type)) return(player); if(!string_compare(str, "here") && (Typeof(player->location) & type)) return(player->location); if((Typeof(player->location) & type) && string_prefix(str, player->location->name)) { add_match(player->location, &matches); } if((o = match_contents(player->location, str, type))) add_match(o, &matches); if(type & TYPE_EXIT) if((o = match_exits(player->location, str))) add_match(o, &matches); } if(type & TYPE_PLAYER) if((o = match_player(player, str))) add_match(o, &matches); if((o = match_contents(player, str, type))) add_match(o, &matches); /* Ambiguity check */ /* If there's more than one match, don't match anything */ if(!matches || !matches[0] || matches[1]) return(NULL); return(matches[0]); } char *no_match(char *str) { char buf[4096]; if(!*str) strcpy(buf, "You must specify a target!"); else sprintf(buf, "I don't see %s here!", str); return(stack_string_alloc(buf, 0)); } char *name(OBJ *thing) { char buf[1024]; char *p; OBJ *lnk = thing; ATTR *coloratr = find_attr("COLOR"), *rainbowatr = find_attr("RAINBOW"); if(!thing) return(""); /* Exits might use their link's color */ if(Typeof(thing) == TYPE_EXIT) { if(thing->link && my_is_color(atr_get_a(thing->link, coloratr))) lnk = thing->link; if(my_is_color(atr_get_a(thing, coloratr))) lnk = thing; } if(my_is_color(atr_get_a(lnk, coloratr))) { if(!*atr_get_a(thing, rainbowatr)) sprintf(buf, "|%s|%s|n|", atr_get_a(lnk, coloratr), thing->name); else sprintf(buf, "|%s|%s|n|", atr_get_a(lnk, coloratr), atr_get_a(thing, rainbowatr)); } else { if(!*atr_get_a(thing, rainbowatr)) sprintf(buf, "|n|%s|n|", thing->name); else sprintf(buf, "|n|%s|n|", atr_get_a(thing, rainbowatr)); } if(Typeof(thing) == TYPE_EXIT && (p = strchr(buf, EXIT_DELIMITER))) *p = '\0'; return(stack_string_alloc(buf, 0)); } char *poss(OBJ *thing) { char format[1024]; char buf[1024]; char *p = thing->name; if(!thing) return(""); if(tolower(*(p+strlen(p)-1) == 's')) sprintf(format, "%s'", atr_get(thing, "RAINBOW")); else sprintf(format, "%s's", atr_get(thing, "RAINBOW")); if(my_is_color(atr_get(thing, "COLOR"))) sprintf(buf, "|%s|%s|n|", atr_get(thing, "COLOR"), format); else sprintf(buf, "|n|%s|n|", format); return(stack_string_alloc(buf, 0)); }