#include <stdio.h> #include <sys/types.h> #include <time.h> #include <ctype.h> #include <math.h> #include <string.h> #include "db.h" #include "config.h" #include "externs.h" #include "funcs.h" struct fun wordlist[] = { {"gt", fun_gt, 2, FNUM}, {"get", fun_get, 2, FSTR}, {"eq", fun_eq, 2, FNUM}, {"gteq", fun_gteq, 2, FNUM}, {"lt", fun_lt, 2, FNUM}, {"end", fun_end, 1, FSTR}, {"tan", fun_tan, 1, FNUM}, {"ln", fun_ln, 1, FNUM}, {"lteq", fun_lteq, 2, FNUM}, {"type", fun_type, 1, FSTR}, {"exp", fun_exp, 1, FNUM}, {"delete", fun_delete, 3, FSTR}, {"rest", fun_rest, 1, FSTR}, {"sgn", fun_sgn, 1, FNUM}, {"chr", fun_chr, 1, FSTR}, {"lattr", fun_lattr, 1, FSTR}, {"rank", fun_rank, 1, FNUM}, {"rand", fun_rand, 1, FNUM}, {"log", fun_log, 1, FNUM}, {"sqrt", fun_sqrt, 1, FNUM}, {"owner", fun_owner, 1, FSTR}, {"extract", fun_extract, 3, FSTR}, {"name", fun_name, 1, FSTR}, {"fsgn", fun_fsgn, 1, FNUM}, {"dtoc", fun_dtoc, 1, FNUM}, {"spc", fun_spc, 1, FSTR}, {"loc", fun_loc, 1, FSTR}, {"start", fun_start, 1, FSTR}, {"dtof", fun_dtof, 1, FNUM}, {"arctan", fun_arctan, 1, FNUM}, {"port", fun_port, 1, FNUM}, {"idle", fun_idle, 1, FNUM}, {"truth", fun_truth, 1, FNUM}, {"num", fun_num, 1, FSTR}, {"time", fun_time, -1, FSTR}, {"tmfrmt", fun_tmfrmt, -1, FSTR}, {"fsqrt", fun_fsqrt, 1, FNUM}, {"last", fun_last, 1, FSTR}, {"has", fun_has, 2, FNUM}, {"strcat", fun_strcat, 2, FSTR}, {"denied", fun_denied, 0, FSTR}, {"sin", fun_sin, 1, FNUM}, {"nspc", fun_nspc, 1, FSTR}, {"abs", fun_abs, 1, FNUM}, {"cos", fun_cos, 1, FNUM}, {"huh", fun_huh, 0, FSTR}, {"base", fun_base, 3, FNUM}, {"link", fun_link, 1, FSTR}, {"mid", fun_mid, 3, FSTR}, {"strlen", fun_strlen, 1, FNUM}, {"anum", fun_anum, 1, FNUM}, {"lwho", fun_lwho, 0, FSTR}, {"quota", fun_quota, 1, FNUM}, {"flip", fun_flip, 1, FSTR}, {"flags", fun_flags, 1, FSTR}, {"wcount", fun_wcount, 1, FNUM}, {"xtime", fun_xtime, -1, FNUM}, {"pos", fun_pos, 2, FNUM}, {"lnum", fun_lnum, 1, FSTR}, {"fabs", fun_fabs, 1, FNUM}, {"first", fun_first, 1, FSTR}, {"rjust", fun_rjust, 2, FSTR}, {"wmatch", fun_wmatch, 2, FNUM}, {"cjust", fun_cjust, 2, FSTR}, {"string", fun_string, 2, FSTR}, {"contype", fun_contype, 2, FNUM}, {"randclr", fun_randclr, 2, FSTR}, {"strchr", fun_strchr, 2, FNUM}, {"comp", fun_comp, 2, FNUM}, {"host", fun_host, 1, FSTR}, {"entrances", fun_entrances, 1, FSTR}, {"ljust", fun_ljust, 2, FSTR}, {"onfor", fun_onfor, 1, FNUM}, {"roman", fun_roman, 1, FSTR}, {"money", fun_money, 1, FNUM}, {"room", fun_room, 1, FSTR}, {"fcomp", fun_fcomp, 2, FNUM}, {"players", fun_players, 0, FSTR}, {"class", fun_class, 1, FSTR}, {"remove", fun_remove, 3, FSTR}, {"arcsin", fun_arcsin, 1, FNUM}, {"arccos", fun_arccos, 1, FNUM}, {"unparse", fun_unparse, 1, FSTR}, {"randword", fun_randword, 1, FSTR}, {"linkup", fun_linkup, 1, FSTR}, {"hasstr", fun_hasstr, 2, FNUM}, {"comma", fun_comma, 1, FSTR}, {"scomp", fun_scomp, 2, FNUM}, {"playmem", fun_playmem, 1, FNUM}, {"quota_left", fun_quota_left, 1, FNUM}, {"mazename", fun_mazename, 0, FSTR}, {"isdigit", fun_isdigit, 1, FNUM}, {"objmem", fun_objmem, 1, FNUM}, {"controls", fun_controls, 3, FNUM}, {"find", fun_find, 1, FSTR}, {"float", fun_float, 2, FNUM}, {"stripcolor", fun_stripcolor, 1, FSTR}, {"descriptor", fun_descriptor, 1, FNUM}, {"haspow", fun_haspow, 2, FNUM}, {"sort", fun_sort, 1, FSTR}, {"", NULL, 0} }; static int istrue(char *str) { return(((strcmp(str, "#-1") == 0) || (strcmp(str, "") == 0) || (strcmp(str, "#-2") == 0) || ((atoi(str) == 0) && isdigit(str[0])))?0:1); } int fun_stripcolor(char *buff, char *args[], OBJ *player) { strcpy(buff, strip_color(args[0])); return(0); } int fun_descriptor(char *buff, char *args[], OBJ *player) { OBJ *who; DDATA *d; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(0); } if(!controls(player, who, POW_HOST)) { strcpy(buff, perm_denied()); return(1); } for(d = descriptor_list;d;d = d->next) if(d->player == who) break; if(!d) { strcpy(buff, "That player is not connected!"); return(1); } sprintf(buff, "%d", d->descriptor); return(0); } int fun_haspow(char *buff, char *args[], OBJ *player) { OBJ *who; int pownum; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } if(!controls(player, who, POW_EXAMINE)) { strcpy(buff, perm_denied()); return(1); } if((pownum = name_to_pow(args[1])) == -1) { strcpy(buff, "No such power!"); return(1); } if(!power(who, pownum)) strcpy(buff, "0"); else strcpy(buff, "1"); return(0); } int fun_sort(char *buff, char *args[], OBJ *player) { int *list = NULL; int temp; int i, j, num_items = 0; char *p, *q, *r; *buff = '\0'; for(p = args[0], q = p;*q;p = q) { while(isspace(*p)) p++; for(q = p;*q && !isspace(*q);q++); if(*q) *q++ = '\0'; for(r = p;*r;r++) { if(!isdigit(*r)) { strcpy(buff, "Illegal character in sort string."); return(1); } } if(!num_items) list = (int *)stack_alloc(sizeof(int), 0, 0); else list = (int *)stack_realloc_tmp(list, sizeof(int)*(num_items+1)); list[num_items++] = atoi(p); } if(num_items < 2) { strcpy(buff, args[0]); return(0); } for(i = 0;i < num_items-1;++i) for(j = i+1;j < num_items;++j) if(list[i] > list[j]) { temp = list[i]; list[i] = list[j]; list[j] = temp; } for(i = 0;i < num_items;++i) { if(!strlen(buff)) sprintf(buff, "%d", list[i]); else sprintf(buff+strlen(buff), " %d", list[i]); } return(0); } int fun_rand(char *buff, char *args[], OBJ *player) { int mod = atoi(args[0]); if(mod < 1) mod = 1; sprintf(buff, "%d", my_rand()%mod); return(0); } int fun_get(char *buff, char *args[], OBJ *player) { OBJ *thing; ATTR *attrib; if(!parse_attrib(player, args[0], &thing, &attrib)) { strcpy(buff, "NO MATCH"); return(1); } if(!can_see_atr(player, thing, attrib)) { strcpy(buff, perm_denied()); return(1); } strcpy(buff, atr_get_a(thing, attrib)); return(0); } int fun_time(char *buff, char *args[], OBJ *player, int nargs) { time_t cl; /* Use supplied x-value if one is given */ /* Otherwise get the current x-value of time */ if(nargs == 2) cl = atol(args[1]); else cl = now; if(nargs == 0) strcpy(buff, mktm(cl, "D", player)); else strcpy(buff, mktm(cl, args[0], player)); return(0); } int fun_xtime(char *buff, char *args[], OBJ *player, int nargs) { time_t cl; if(nargs == 0) cl = now; else { cl = mkxtime(args[0], player, (nargs > 1)?args[1]:""); if(cl == -1L) { strcpy(buff, "#-1"); return(1); } } sprintf(buff, "%ld", cl); return(0); } int fun_objmem(char *buff, char *args[], OBJ *player) { OBJ *thing; if(!(thing = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } if(!controls(player, thing, POW_DB)) { strcpy(buff, perm_denied()); return(1); } sprintf(buff, "%d", mem_usage(thing)); return(0); } int fun_playmem(char *buff, char *args[], OBJ *player) { int tot = 0; OBJ *thing; OBJ *o; if(!(thing = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } if(!controls(player, thing, POW_DB)) { strcpy(buff, perm_denied()); return(1); } for(o = player_list;o;o = o->next) if(o->owner == thing) tot += mem_usage(o); for(o = thing_list;o;o = o->next) if(o->owner == thing) tot += mem_usage(o); for(o = room_list;o;o = o->next) if(o->owner == thing) tot += mem_usage(o); for(o = exit_list;o;o = o->next) if(o->owner == thing) tot += mem_usage(o); sprintf(buff, "%d", tot); return(0); } int fun_mid(char *buff, char *args[], OBJ *player) { int l = atoi(args[1]), len = atoi(args[2]); char *str; if(l < 0 || len < 0 || (len+l) > 1000) { strcpy(buff, "OUT OF RANGE"); return(1); } str = strip_color(args[0]); if(l < strlen(str)) strcpy(buff, str+l); else *buff = '\0'; buff[len] = '\0'; return(0); } int fun_truth(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", (istrue(args[0])?1:0)); return(0); } int fun_denied(char *buff, char *args[], OBJ *player) { extern int num_perm_denied; extern char *perm_messages[]; sprintf(buff, "|+R|%s|n|", perm_messages[my_rand()%num_perm_denied]); return(0); } int fun_huh(char *buff, char *args[], OBJ *player) { extern int num_bad_cmd_msgs; extern char *bad_cmd_msgs[]; sprintf(buff, "|+B|%s|n|", bad_cmd_msgs[my_rand()%num_bad_cmd_msgs]); return(0); } int fun_base(char *buff, char *args[], OBJ *player) { int i, digit, decimal, neg, oldbase, newbase; char tmpbuf[1000]; oldbase = atoi(args[1]); newbase = atoi(args[2]); if((oldbase < 2) || (oldbase > 36) || (newbase < 2) || (newbase > 36)) { strcpy(buff, "BASES MUST BE BETWEEN 2 AND 36"); return(1); } neg = 0; if(args[0][0] == '-') { neg = 1; args[0][0] = '0'; } decimal = 0; for(i = 0;args[0][i] != 0;i++) { decimal *= oldbase; if(('0' <= args[0][i]) && (args[0][i] <= '9')) digit = args[0][i]-'0'; else if(('a' <= args[0][i]) && (args[0][i] <= 'z')) digit = args[0][i]+10-'a'; else if(('A' <= args[0][i]) && (args[0][i] <= 'Z')) digit = args[0][i]+10-'A'; else { strcpy(buff, "ILLEGAL DIGIT"); return(1); } if(digit >= oldbase) { strcpy(buff, "DIGIT OUT OF RANGE"); return(1); } decimal += digit; } strcpy(buff, ""); strcpy(tmpbuf, ""); i = 0; while(decimal > 0) { strcpy(tmpbuf, buff); digit = (decimal%newbase); if(digit < 10) sprintf(buff, "%d%s", digit, tmpbuf); else sprintf(buff, "%c%s", digit+'a'-10, tmpbuf); decimal /= newbase; i++; } if(neg) { strcpy(tmpbuf, buff); sprintf(buff, "-%s", tmpbuf); } return(0); } int fun_roman(char *buff, char *args[], OBJ *player) { char *p; int num; int i; struct { char chr; int num; } roman[8]; roman[0].chr = 'N'; roman[0].num = 5000; roman[1].chr = 'M'; roman[1].num = 1000; roman[2].chr = 'D'; roman[2].num = 500; roman[3].chr = 'C'; roman[3].num = 100; roman[4].chr = 'L'; roman[4].num = 50; roman[5].chr = 'X'; roman[5].num = 10; roman[6].chr = 'V'; roman[6].num = 5; roman[7].chr = 'I'; roman[7].num = 1; for(p = args[0];*p && isdigit(*p);++p); if(*p) { strcpy(buff, "ARG must be a number!"); return(1); } num = atoi(args[0]); if(!num) { strcpy(buff, "0"); return(0); } if(num >= 10000) { strcpy(buff, ""); return(0); } p = buff; while(num) { for(i = 0;i < 8;++i) if(num >= roman[i].num) break; if(num >= (roman[i].num)*4) { num -= (roman[i].num)*4; *p++ = roman[i].chr; *p++ = roman[i+1].chr; } else { num -= roman[i].num; *p++ = roman[i].chr; } } *p = '\0'; return(0); } int fun_sgn(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", atoi(args[0]) > 0?1:atoi(args[0]) < 0?-1:0); return(0); } int fun_sqrt(char *buff, char *args[], OBJ *player) { extern double sqrt P((double)); int k = atoi(args[0]); if(k < 0) k = (-k); sprintf(buff, "%d", (int)sqrt((double)k)); return(0); } int fun_abs(char *buff, char *args[], OBJ *player) { extern int abs P((int)); sprintf(buff, "%d", abs(atoi(args[0]))); return(0); } /* Read first word from a string */ int fun_first(char *buff, char *args[], OBJ *player) { char *s = args[0]; char *b; /* Get rid of leading space */ while(*s && isspace(*s)) s++; b = s; while(*s && !isspace(*s)) s++; *s++ = '\0'; strcpy(buff, b); return(0); } int fun_last(char *buff, char *args[], OBJ *player) { char *p; if(!strchr(args[0], ' ')) { strcpy(buff, args[0]); return(0); } p = &args[0][strlen(args[0])-1]; while(*(--p) != ' '); strcpy(buff, p+1); return(0); } int fun_rest(char *buff, char *args[], OBJ *player) { char *s = args[0]; /* Skip leading space */ while(*s && isspace(*s)) s++; /* Skip firsts word */ while(*s && !isspace(*s)) s++; /* Skip leading space */ while(*s && isspace(*s)) s++; strcpy(buff, s); return(0); } int fun_flags(char *buff, char *args[], OBJ *player) { OBJ *thing; if(!(thing = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buff, unparse_flags(thing)); return(0); } int fun_money(char *buff, char *args[], OBJ *player) { OBJ *who; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } if(!controls(player, who, POW_FUNCTIONS)) { strcpy(buff, perm_denied()); return(1); } sprintf(buff, "%ld", Pennies(who)); return(0); } int fun_quota_left(char *buff, char *args[], OBJ *player) { OBJ *who; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } if(!controls(player, who, POW_FUNCTIONS)) { strcpy(buff, perm_denied()); return(1); } sprintf(buff, "%d", atoi(atr_get(who, "QUOTA"))-owns_stuff(who)); return(0); } int fun_mazename(char *buff, char *args[], OBJ *player) { strcpy(buff, config.maze_name); return(0); } int fun_quota(char *buff, char *args[], OBJ *player) { OBJ *who; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } if(!controls(player, who, POW_FUNCTIONS)) { strcpy(buff, perm_denied()); return(1); } strcpy(buff, atr_get(who, "QUOTA")); return(0); } int fun_strlen(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", strlen(args[0])-str_colorlen(args[0])); return(0); } int fun_comp(char *buff, char *args[], OBJ *player) { int x; x = (atoi(args[0])-atoi(args[1])); if(x > 0) strcpy(buff, "1"); else if(x < 0) strcpy(buff, "-1"); else strcpy(buff, "0"); return(0); } int fun_scomp(char *buff, char *args[], OBJ *player) { int x; x = strcmp(args[0], args[1]); if(x > 0) strcpy(buff, "1"); else if(x < 0) strcpy(buff, "-1"); else strcpy(buff, "0"); return(0); } int fun_num(char *buff, char *args[], OBJ *player) { OBJ *who; if(!(who = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } sprintf(buff, "#%d", who->dbref); return(0); } int fun_loc(char *buff, char *args[], OBJ *player) { OBJ *it; if(!(it = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } if(IS(it, TYPE_PLAYER, DARK) && !controls(player, it, POW_FUNCTIONS)) { strcpy(buff, perm_denied()); return(1); } sprintf(buff, "#%d", it->location->dbref); return(0); } int fun_room(char *buff, char *args[], OBJ *player) { OBJ *who; OBJ *oldloc; if(!(who = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } if(IS(who, TYPE_PLAYER, DARK) && !controls(player, who, POW_FUNCTIONS)) { strcpy(buff, perm_denied()); return(1); } for(oldloc = getloc(who);getloc(oldloc) != oldloc;oldloc = getloc(who)); strcpy(buff, tprintf("#%d", oldloc->dbref)); return(0); } int fun_link(char *buff, char *args[], OBJ *player) { OBJ *it; if(!(it = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } if(it->owner != player && !controls(player, it, POW_FUNCTIONS)) { strcpy(buff, perm_denied()); return(1); } sprintf(buff, "#%d", it->link->dbref); return(0); } int fun_linkup(char *buff, char *args[], OBJ *player) { OBJ *it, *o; int len = 0; if(!(it = match_object(player, args[0], TYPE_ROOM))) { strcpy(buff, no_match(args[0])); return(1); } if(it->owner != player && !controls(player, it, POW_FUNCTIONS)) { strcpy(buff, perm_denied()); return(1); } *buff = '\0'; for(o = player_list;o;o = o->next) { if(o->link == it) { if(len) sprintf(buff+strlen(buff), " #%d", o->dbref); else { sprintf(buff, "#%d", o->dbref); len = 1; } } } for(o = thing_list;o;o = o->next) { if(o->link == it) { if(len) sprintf(buff+strlen(buff), " #%d", o->dbref); else { sprintf(buff, "#%d", o->dbref); len = 1; } } } for(o = exit_list;o;o = o->next) { if(o->link == it) { if(len) sprintf(buff+strlen(buff), " #%d", o->dbref); else { sprintf(buff, "#%d", o->dbref); len = 1; } } } return(0); } int fun_class(char *buff, char *args[], OBJ *player) { OBJ *it; if(!(it = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buff, class_to_name(get_class(it))); return(0); } int fun_rank(char *buff, char *args[], OBJ *player) { OBJ *it; if(!(it = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } sprintf(buff, "%d", get_class(it)); return(0); } int fun_has(char *buff, char *args[], OBJ *player) { OBJ *user, *obj; OBJ *o; if(!(user = match_object(player, args[0], TYPE_MASK & ~TYPE_EXIT))) { strcpy(buff, no_match(args[0])); return(1); } if(!(obj = match_object(player, args[1], TYPE_MASK & ~TYPE_ROOM))) { strcpy(buff, no_match(args[1])); return(1); } strcpy(buff, "0"); for(o = user->contents;o;o = o->next_con) if(o == obj) { strcpy(buff, "1"); return(0); } for(o = user->exits;o;o = o->next_exit) if(o == obj) { strcpy(buff, "1"); return(0); } return(0); } int fun_owner(char *buff, char *args[], OBJ *player) { OBJ *it; if(!(it = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } sprintf(buff, "#%d", it->owner->dbref); return(0); } int fun_name(char *buff, char *args[], OBJ *player) { OBJ *it; if(!(it = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buff, name(it)); return(0); } int fun_unparse(char *buff, char *args[], OBJ *player) { OBJ *it; if(!(it = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buff, unparse_object(it, it)); return(0); } int fun_pos(char *buff, char *args[], OBJ *player) { int i = 1; char *t, *u, *s = args[1]; while(*s) { for(u = s, t = args[0];*t && *t == *u;++t, ++u); /* Whole loop */ if(!*t) { sprintf(buff, "%d", i); return(0); } ++i; ++s; } strcpy(buff, "0"); return(0); } int fun_delete(char *buff, char *args[], OBJ *player) { char *s = buff, *t = args[0]; int i, l = atoi(args[1]), len = atoi(args[2]); int a0len = strlen(args[0]); if((l < 0) || (len < 0) || (len+l >= 1000)) { strcpy(buff, "OUT OF RANGE"); return(1); } for(i = 0;i < l && *s;i++) *s++ = *t++; if(len+l >= a0len) { *s = '\0'; return(0); } t += len; while((*s++ = *t++)); return(0); } int fun_remove(char *buff, char *args[], OBJ *player) { char *s = buff, *t = args[0]; int w = atoi(args[1]), num = atoi(args[2]), i; if(w < 1) { strcpy(buff, "OUT OF RANGE"); return(1); } for(i = 1;i < w && *t;i++) { while(*t && *t != ' ') *s++ = *t++; while(*t && *t == ' ') *s++ = *t++; } for(i = 0;i < num && *t;i++) { while(*t && *t != ' ') t++; while(*t && *t == ' ') t++; } if(!*t) { if(s != buff) s--; *s = '\0'; return(0); } while((*s++ = *t++)); return(0); } int fun_extract(char *buff, char *args[], OBJ *player) { int start = atoi(args[1]), len = atoi(args[2]); char *s = args[0], *r; if((start < 1) || (len < 1)) { *buff = 0; return(0); } start--; while(start && *s) { while(*s && (*s == ' ')) s++; while(*s && (*s != ' ')) s++; start--; } while(*s && (*s == ' ')) s++; r = s; while(len && *s) { while(*s && (*s == ' ')) s++; while(*s && (*s != ' ')) s++; len--; } *s = 0; strcpy(buff, r); return(0); } int fun_wmatch(char *buff, char *args[], OBJ *player) { char *string = args[0], *word = args[1], *s, *t; int count = 0, done = 0; for(s = string;*s && !done;s++) { count++; while(isspace(*s) && *s) s++; t = s; while(!isspace(*t) && *t) t++; done = (!*t)?1:0; *t = '\0'; if(!string_compare(s, word)) { sprintf(buff, "%d", count); return(0); } s = t; } sprintf(buff, "0"); return(0); } int fun_strcat(char *buff, char *args[], OBJ *player) { strcpy(buff, tprintf("%s%s", args[0], args[1])); return(0); } int fun_controls(char *buff, char *args[], OBJ *player) { OBJ *who, *object; int power; if(!(who = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } if(!(object = match_object(player, args[1], NOTYPE))) { strcpy(buff, no_match(args[1])); return(1); } if((power = name_to_pow(args[2])) < 0) { strcpy(buff, "No such power!"); return(1); } sprintf(buff, "%d", controls(who, object, power)); return(0); } int fun_entrances(char *buff, char *args[], OBJ *player) { OBJ *it, *o; int control_here; if(!(it = match_object(player, args[0], TYPE_ROOM))) { strcpy(buff, no_match(args[0])); return(1); } *buff = '\0'; /* This is just so we don't have to call controls() every time through the loop */ control_here = controls(player, it, POW_FUNCTIONS); if(!control_here) control_here = controls(player, it, POW_EXAMINE); for(o = exit_list;o;o = o->next) if(o->link == it) if(control_here || controls(player, o, POW_FUNCTIONS) || controls(player, o, POW_EXAMINE)) { if(*buff) strcpy(buff+strlen(buff), tprintf(" #%d", o->dbref)); else sprintf(buff, "#%d", o->dbref); } return(0); } int fun_fsgn(char *buff, char *args[], OBJ *player) { if(atof(args[0]) < 0) sprintf(buff, "-1"); else if(atof(args[0]) > 0) sprintf(buff, "1"); else strcpy(buff, "0"); return(0); } int fun_fsqrt(char *buff, char *args[], OBJ *player) { if(atoi(args[0]) < 0) sprintf(buff, "%f", (float)0); else sprintf(buff, "%f", sqrt(atof(args[0]))); return(0); } int fun_fabs(char *buff, char *args[], OBJ *player) { if(atof(args[0]) < 0) sprintf(buff, "%f", -atof(args[0])); else strcpy(buff, args[0]); return(0); } int fun_fcomp(char *buff, char *args[], OBJ *player) { char buf[90]; char *k = buf; sprintf(buf, "%f", atof(args[0])-atof(args[1])); fun_fsgn(buff, &k, player); return(0); } int fun_exp(char *buff, char *args[], OBJ *player) { if(atof(args[0]) > 99 || atof(args[0]) < -99) { sprintf(buff, "Error - operand must be from -99 to 99."); return(1); } sprintf(buff, "%f", exp(atof(args[0]))); return(0); } int fun_log(char *buff, char *args[], OBJ *player) { if(atof(args[0]) < 0) sprintf(buff, "%f", (float)0); else sprintf(buff, "%f", log10(atof(args[0]))); return(0); } int fun_ln(char *buff, char *args[], OBJ *player) { sprintf(buff, "%f", log(atof(args[0]))); return(0); } int fun_arctan(char *buff, char *args[], OBJ *player) { if(atof(args[0]) > 1 || atof(args[0]) < -1) { sprintf(buff, "Error - operand must be from -1 to 1."); return(1); } sprintf(buff, "%f", atan(atof(args[0]))); return(0); } int fun_arccos(char *buff, char *args[], OBJ *player) { if(atof(args[0]) > 1 || atof(args[0]) < -1) { sprintf(buff, "Error - operand must be from -1 to 1."); return(1); } sprintf(buff, "%f", acos(atof(args[0]))); return(0); } int fun_arcsin(char *buff, char *args[], OBJ *player) { if(atof(args[0]) > 1 || atof(args[0]) < -1) { sprintf(buff, "Error - operand must be from -1 to 1."); return(1); } sprintf(buff, "%f", asin(atof(args[0]))); return(0); } int fun_tan(char *buff, char *args[], OBJ *player) { if(atof(args[0]) > 1 || atof(args[0]) < -1) { sprintf(buff, "Error - operand must be from -1 to 1."); return(1); } sprintf(buff, "%f", tan(atof(args[0]))); return(0); } int fun_cos(char *buff, char *args[], OBJ *player) { if(atof(args[0]) > 1 || atof(args[0]) < -1) { sprintf(buff, "Error - operand must be from -1 to 1."); return(1); } sprintf(buff, "%f", cos(atof(args[0]))); return(0); } int fun_sin(char *buff, char *args[], OBJ *player) { if(atof(args[0]) > 1 || atof(args[0]) < -1) { sprintf(buff, "Error - operand must be from -1 to 1."); return(1); } sprintf(buff, "%f", sin(atof(args[0]))); return(0); } int fun_eq(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", (atof(args[0]) == atof(args[1]))); return(0); } int fun_gt(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", (atof(args[0]) > atof(args[1]))); return(0); } int fun_lt(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", (atof(args[0]) < atof(args[1]))); return(0); } int fun_gteq(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", (atof(args[0]) >= atof(args[1]))); return(0); } int fun_lteq(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", (atof(args[0]) <= atof(args[1]))); return(0); } int fun_randclr(char *buff, char *args[], OBJ *player) { char *p = args[1]; char colors[500][5]; char buf[1024]; int ctr = 0; char *b; int i; if(strlen(args[0]) > 100) { strcpy(buff, "arg1 out of range!"); return(1); } while(ctr < 500) { b = buf; while(*p && *p != ' ') *b++ = *p++; *b = '\0'; if(strlen(buf) > 4) { strcpy(buff, "Invalid color in arg2!"); return(1); } strcpy(colors[ctr++], buf); if(!*p) break; p++; } if(ctr == 500) { strcpy(buff, "Limit of 500 colors in arg2!"); return(1); } for(i = 0;i < ctr;++i) if(!my_is_color(colors[i])) { sprintf(buff, "Invalid color '%s' in arg2!", colors[i]); return(1); } p = args[0]; b = buff; *b = '\0'; while(*p) { while(*p == ' ') *b++ = *p++; *b++ = '|'; *b = '\0'; strcat(b, colors[my_rand()%ctr]); b = &buff[strlen(buff)]; *b++ = '|'; *b++ = *p++; } *b = '\0'; return(0); } int fun_find(char *buff, char *args[], OBJ *player) { int ctr = 0; OBJ *thing; *buff = '\0'; for(thing = player_list;thing;thing = thing->next) { if(controls(player, thing, POW_EXAMINE) && string_match(thing->name, args[0])) { if(ctr++ > 99) { strcpy(buff, "TOO MANY MATCHES"); return(1); } if(*buff) sprintf(buff, "%d", thing->dbref); else sprintf(buff+strlen(buff), " #%d", thing->dbref); } } for(thing = thing_list;thing;thing = thing->next) { if(controls(player, thing, POW_EXAMINE) && string_match(thing->name, args[0])) { if(ctr++ > 99) { strcpy(buff, "TOO MANY MATCHES"); return(1); } if(*buff) sprintf(buff, "%d", thing->dbref); else sprintf(buff+strlen(buff), " #%d", thing->dbref); } } for(thing = room_list;thing;thing = thing->next) { if(controls(player, thing, POW_EXAMINE) && string_match(thing->name, args[0])) { if(ctr++ > 99) { strcpy(buff, "TOO MANY MATCHES"); return(1); } if(*buff) sprintf(buff, "%d", thing->dbref); else sprintf(buff+strlen(buff), " #%d", thing->dbref); } } return(0); } int fun_float(char *buff, char *args[], OBJ *player) { int format; char *p; char no_zeros = 0; for(p = args[0];*p && (isdigit(*p) || *p == '.');p++); if(*p) { strcpy(buff, args[0]); return(0); } p = args[1]; if(*p == '-') { no_zeros = 1; p++; } while(*p && isdigit(*p)) p++; if(*p) { strcpy(buff, "INVALID FORMAT: arg2"); return(1); } format = atoi(args[1]+((*(args[1]) == '-')?1:0)); if(format > 99) { strcpy(buff, "arg2 OUT OF RANGE"); return(1); } if(!(p = strchr(args[0], '.'))) { if(no_zeros || !format) { strcpy(buff, args[0]); return(0); } sprintf(buff, "%s.", args[0]); p = buff+strlen(buff); while(format--) *p++ = '0'; *p = '\0'; return(0); } p++; /* There shouldn't be 2 '.' in a number */ if(strchr(p, '.')) { strcpy(buff, args[0]); return(0); } while(*p && format--) p++; if(!*p) { strcpy(buff, args[0]); if(no_zeros) { p = buff+strlen(buff)-1; if(*p == '.') *p = '\0'; return(0); } p = buff+strlen(buff); while(format--) *p++ = '0'; *p = '\0'; return(0); } *(p+1) = '\0'; if(atoi(p) < 5) { *p-- = '\0'; if(no_zeros) while(*p == '0') *p-- = '\0'; if(*p == '.') *p = '\0'; strcpy(buff, args[0]); return(0); } /* We have to round the number */ *p-- = '\0'; while(p >= args[0]) { if(*p == '.') { p--; continue; } if(*p == '9') { *p-- = '0'; continue; } *p = (*p)+1; break; } if(p < args[0]) { if(no_zeros) { p = args[0]+strlen(args[0])-1; while(*p == '0') *p-- = '\0'; } p = args[0]+strlen(args[0])-1; if(*p == '.') *p = '\0'; sprintf(buff, "1%s", args[0]); return(0); } if(no_zeros) { p = args[0]+strlen(args[0])-1; while(*p == '0') *p-- = '\0'; } p = args[0]+strlen(args[0])-1; if(*p == '.') *p = '\0'; strcpy(buff, args[0]); return(0); } int fun_nspc(char *buff, char *args[], OBJ *player) { char *p; char *b = buff; if(!*args[0]) { strcpy(buff, ""); return(0); } p = &args[0][strlen(args[0])-1]; while(p != args[0] && *p == ' ') p--; if(p == args[0]) { strcpy(buff, ""); return(0); } *(p+1) = '\0'; p = args[0]; while(*p && *p == ' ') p++; while(*p) *b++ = *p++; *b = '\0'; return(0); } int fun_wcount(char *buff, char *args[], OBJ *player) { char *p = args[0]; int num = 0; while(*p) { while(*p && isspace(*p)) p++; if(*p) num++; while(*p && !isspace(*p)) p++; } sprintf(buff, "%d", num); return(0); } int fun_lwho(char *buff, char *args[], OBJ *player) { char buf[1024]; DDATA *d; *buf = '\0'; for(d = descriptor_list;d;d = d->next) { if(check_state(d, STATE_CONNECTED)) { if((controls(player, d->player, POW_WHO)) || could_doit(player, d->player, "LHIDE")) { if(*buf) sprintf(buf+strlen(buf), " #%d", d->player->dbref); else sprintf(buf, "#%d", d->player->dbref); } } } strcpy(buff, buf); return(0); } int fun_spc(char *buff, char *args[], OBJ *player) { char tbuf1[1024]; int i; int s = atoi(args[0]); if(s <= 0) { strcpy(buff, ""); return(0); } if(s > 950) s = 950; for(i = 0;i < s;i++) tbuf1[i] = ' '; tbuf1[i] = '\0'; strcpy(buff, tbuf1); return(0); } static void do_flip(char *s, char *r) { char *p; p = strlen(s)+r; for(*p-- = '\0';*s;p--, s++) *p = *s; } int fun_flip(char *buff, char *args[], OBJ *player) { do_flip(args[0], buff); return(0); } int fun_lnum(char *buff, char *args[], OBJ *player) { int x, i; x = atoi(args[0]); if((x > 250) || (x < 0)) { strcpy(buff, "#-1 Number Out Of Range"); return(1); } else { strcpy(buff, "0"); for(i = 1;i < x;i++) sprintf(buff, "%s %d", buff, i); } return(0); } int fun_string(char *buf, char *args[], OBJ *player) { int num, i; char *letter; *buf = '\0'; num = atoi(args[1]); letter = args[0]; if(((num*strlen(letter)) <= 0) || ((num*strlen(letter)) > 950)) { strcpy(buf, "#-1 Out Of Range"); return(1); } *buf = '\0'; for(i = 0;i < num;i++) strcat(buf, letter); return(0); } int fun_cjust(char *buff, char *args[], OBJ *player) { strcpy(buff, my_center(args[0], atoi(args[1]))); return(0); } int fun_ljust(char *buff, char *args[], OBJ *player) { strcpy(buff, my_ljust(args[0], atoi(args[1]))); return(0); } int fun_rjust(char *buff, char *args[], OBJ *player) { int number = atoi(args[1]); char *text; int leader; char tbuf1[1000]; char buf[1000]; int i; if(number <= 0 || number > 950) { sprintf(buff, "#-1 Number out of range."); return(1); } text = args[0]; leader = number-strlen(text); if(leader <= 0) { strcpy(buff, text); buff[number] = 0; return(0); } if(leader > 950) leader = 950 - 1; for(i = 0;i < leader;i++) tbuf1[i] = ' '; tbuf1[i] = '\0'; sprintf(buf, "%s%s", tbuf1, text); strcpy(buff, buf); return(0); } int fun_lattr(char *buff, char *args[], OBJ *player) { OBJ *it; int len = 0; ALIST *a; char temp[1024]; if(!(it = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } *buff = '\0'; if(!it->attrlist) return(0); for(a = it->attrlist;a;a = a->next) { if(can_see_atr(player, it, a->attr)) { sprintf(temp, (*buff)?" %s":"%s", unparse_attr(a)); if((len+strlen(temp)) > 950) { strcat(buff, "#-1"); return(1); } strcpy(buff+len, temp); len += strlen(temp); } } return(0); } int fun_type(char *buff, char *args[], OBJ *player) { OBJ *it; if(!(it = match_object(player, args[0], NOTYPE))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buff, type_to_name(Typeof(it))); return(0); } int fun_idle(char *buff, char *args[], OBJ *player) { char buf[1024]; DDATA *d; OBJ *who; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buf, "#-1"); for(d = descriptor_list;d;d = d->next) { if(check_state(d, STATE_CONNECTED)) { if((controls(player, d->player, POW_WHO)) || could_doit(player, d->player, "LHIDE")) { if(d->player == who) { sprintf(buf, "%ld", (now-d->last_time)); break; } } } } strcpy(buff, buf); return(0); } int fun_onfor(char *buff, char *args[], OBJ *player) { char buf[1024]; DDATA *d; OBJ *who; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buf, "#-1"); for(d = descriptor_list;d;d = d->next) { if(check_state(d, STATE_CONNECTED)) { if((controls(player, d->player, POW_WHO)) || could_doit(player, d->player, "LHIDE")) { if(d->player == who) { sprintf(buf, "%ld", (now-d->connected_at)); break; } } } } strcpy(buff, buf); return(0); } int fun_port(char *buff, char *args[], OBJ *player) { char buf[1024]; DDATA *d; OBJ *who; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buf, "#-1"); for(d = descriptor_list;d;d = d->next) { if(check_state(d, STATE_CONNECTED)) { if((controls(player, d->player, POW_WHO)) || could_doit(player, d->player, "LHIDE")) { if(d->player == who) { sprintf(buf, "%d", ntohs(d->address.sin_port)); break; } } } } strcpy(buff, buf); return(0); } int fun_host(char *buff, char *args[], OBJ *player) { char buf[1024]; DDATA *d; OBJ *who; if(!(who = match_object(player, args[0], TYPE_PLAYER))) { strcpy(buff, no_match(args[0])); return(1); } strcpy(buf, "#-1"); for(d = descriptor_list;d;d = d->next) { if(check_state(d, STATE_CONNECTED)) { if((controls(player, d->player, POW_WHO)) || could_doit(player, d->player, "LHIDE")) { if(d->player == who && controls(player, who, POW_HOST)) { sprintf(buf, "%s@%s", d->user, d->addr); break; } } } } strcpy(buff, buf); return(0); } int fun_tmfrmt(char *buff, char *args[], OBJ *player, int nargs) { long num = atol(args[0]); int num_fields = 6; if(nargs < 1 || nargs > 2) { strcpy(buff, "Number of arguments must be 1 or 2"); return(1); } if(num < 0) { strcpy(buff, "Argument must be positive!"); return(1); } if(nargs == 2) { num_fields = atoi(args[1]); if(num_fields < 1 || num_fields > 6) { strcpy(buff, "Number of fields must be between 1 and 6"); return(1); } } strcpy(buff, time_format(num, num_fields)); return(0); } int fun_comma(char *buff, char *args[], OBJ *player) { int i; if(!isdigit(args[0][0]) && args[0][0] != '-'&& args[0][0] != '.') { strcpy(buff, "Expecting a number."); return(1); } for(i = 1;i < strlen(args[0]);++i) if(!isdigit(args[0][i]) && args[0][i] != '.') { strcpy(buff, "Expecting a number."); return(1); } strcpy(buff, comma(args[0])); return(0); } int fun_players(char *buff, char *args[], OBJ *player) { OBJ *o; char buf[20]; *buff = '\0'; for(o = player_list;o;o = o->next) { sprintf(buf, "#%d", o->dbref); if(strlen(buff)+strlen(buf) > 899) break; if(*buff) sprintf(buff+strlen(buff), " %s", buf); else strcpy(buff, buf); } return(0); } int fun_start(char *buff, char *args[], OBJ *player) { sprintf(buff, "%c", *args[0]); return(0); } int fun_end(char *buff, char *args[], OBJ *player) { char *p; p = &args[0][strlen(args[0])-1]; sprintf(buff, "%c", *p); return(0); } int fun_strchr(char *buff, char *args[], OBJ *player) { if(strlen(args[1]) > 1) { strcpy(buff, "arg2 must be a single character"); return(1); } if(strchr(args[0], *args[1])) strcpy(buff, "1"); else strcpy(buff, "0"); return(0); } int fun_hasstr(char *buff, char *args[], OBJ *player) { if(strstr(args[0], args[1])) strcpy(buff, "1"); else strcpy(buff, "0"); return(0); } int fun_anum(char *buff, char *args[], OBJ *player) { if(strlen(args[0]) > 1) { strcpy(buff, "Expecting a single character."); return(1); } sprintf(buff, "%d", *args[0]); return(0); } int fun_dtoc(char *buff, char *args[], OBJ *player) { char *p = args[0]; int deg; if(*p == '-') p++; while(*p) { if(!isdigit(*p) && *p != '.') { strcpy(buff, "Expecting a number"); return(1); } p++; } deg = atof(args[0]); sprintf(buff, "%.2f", (deg-32)*5./9.); return(0); } int fun_dtof(char *buff, char *args[], OBJ *player) { char *p = args[0]; int deg; if(*p == '-') p++; while(*p) { if(!isdigit(*p) && *p != '.') { strcpy(buff, "Expecting a number"); return(1); } p++; } deg = atof(args[0]); sprintf(buff, "%.2f", (9.*deg/5.)+32); return(0); } int fun_randword(char *buff, char *args[], OBJ *player) { int num_words = 0; char *p = args[0]; int which_one; char buf[100]; char *b; while(*p) /* Count how many words there are */ { if(*p++ == ' ') num_words++; } num_words++; if(num_words <= 0) { strcpy(buff, ""); return(0); } which_one = (my_rand()%num_words)+1; p = args[0]; while(which_one--) /* Fill buf with the right one */ { b = buf; while(*p && *p != ' ') *b++ = *p++; *b = '\0'; if(!*p) /* Shouldn't really need this...but just in case */ break; p++; } strcpy(buff, buf); return(0); } int fun_chr(char *buff, char *args[], OBJ *player) { if(!power(player, POW_FUNCTIONS)) { strcpy(buff, perm_denied()); return(1); } sprintf(buff, "%c", atoi(args[0])); return(0); } int fun_isdigit(char *buff, char *args[], OBJ *player) { sprintf(buff, "%d", (isdigit(args[0][0]))?1:0); return(0); } int fun_contype(char *buff, char *args[], OBJ *player) { OBJ *loc, *thing; int type; if(!(loc = match_object(player, args[0], TYPE_MASK & ~TYPE_EXIT))) { strcpy(buff, no_match(args[0])); return(1); } if(string_prefix("Player", args[1])) type = TYPE_PLAYER; else if(string_prefix("Thing", args[1])) type = TYPE_THING; else if(string_prefix("Room", args[1])) type = TYPE_ROOM; else if(string_prefix("Exit", args[1])) type = TYPE_EXIT; else { strcpy(buff, "Unknown type!"); return(1); } for(thing = loc->contents;thing;thing = thing->next_con) { if(Typeof(thing) == type) { if(type == TYPE_PLAYER && !is_connected_raw(thing)) continue; strcpy(buff, "1"); return(0); } } strcpy(buff, "0"); return(0); } void info_funcs(OBJ *player) { int i; notify(player, tprintf("builtin functions:")); notify(player, tprintf("%10s %s","function", "nargs")); for(i = 0;*(wordlist[i].name);i++) if(wordlist[i].name && wordlist[i].name[0]) { if(wordlist[i].nargs == -1) notify(player, tprintf("%10s any", wordlist[i].name)); else notify(player, tprintf("%10s %d", wordlist[i].name, wordlist[i].nargs)); } } /* Function to split up a list given a seperator */ /* NOTE: str will get hacked up */ char *parse_up(char **args, int delimit) { char **str = args; int deep = 0; char *s = *str, *os = *str; if(!*s) return(NULL); while(*s && (*s != delimit)) if(*s++ == '{') { deep = 1; while(deep && *s) switch(*s++) { case '{': deep++; break; case '}': deep--; break; } } if(*s) *s++ = '\0'; *str = s; return(os); } struct fun *lookup_func(char *str) { FUN *ptr = NULL; int i; for(i = 0;*(wordlist[i].name);++i) if(!string_compare(wordlist[i].name, str)) { ptr = &wordlist[i]; break; } return(ptr); }