/* $Header: /belch_a/users/rearl/tinymuck/src/RCS/predicates.c,v 1.8 90/09/18 08:01:39 rearl Exp $ */ /* * $Log: predicates.c,v $ * Revision 1.8 90/09/18 08:01:39 rearl * Fixed a few broken things. * * Revision 1.7 90/09/16 04:42:42 rearl * Preparation code added for disk-based MUCK. * * Revision 1.6 90/09/10 02:22:30 rearl * Fixed some calls to pronoun_substitute. * * Revision 1.5 90/08/27 03:32:49 rearl * Major changes on several predicates, usage... * * Revision 1.4 90/08/15 03:07:34 rearl * Macroified some things. Took out #ifdef GENDER. * * Revision 1.3 90/08/06 02:46:30 rearl * Put can_link() back in. Added restricted() for flags. * With #define GOD_PRIV, sub-wizards can no longer set other * players to Wizard. * * Revision 1.2 90/08/02 18:54:04 rearl * Fixed controls() to return TRUE if exit is unlinked. Everyone * controls an unlinked exit. Got rid of can_link(). * * Revision 1.1 90/07/19 23:03:58 casie * Initial revision * * */ #include "copyright.h" #include "config.h" /* Predicates for testing various conditions */ #include <ctype.h> #include "db.h" #include "interface.h" #include "params.h" #include "externs.h" int can_hear(dbref who) { return (notify_internal(who, NULL) || ((FLAGS(who)&PUPPET) && Typeof(who) != TYPE_PLAYER) || get_attr(who,"listen")); } int can_link_to(dbref who, object_flag_type what_type, dbref where) { if (where == HOME) return 1; switch (what_type) { case TYPE_GARBAGE: return 0; break; case TYPE_EXIT: return (controls(who, where) || (FLAGS(where) & LINK_OK)); /*NOTREACHED*/ break; case TYPE_PLAYER: return (Typeof(where) == TYPE_ROOM && (controls(who, where) || Linkable(where))); /*NOTREACHED*/ break; case TYPE_ROOM: case TYPE_THING: return ((Typeof(where) == TYPE_ROOM || Typeof(where) == TYPE_PLAYER) && (controls(who, where) || Linkable(where))); /*NOTREACHED*/ break; case NOTYPE: #ifdef ABODE return (controls(who, where) || ((!(Typeof(where) == TYPE_PLAYER)) && (FLAGS(where) & ABODE)) || (FLAGS(where) & LINK_OK)); #else /* ABODE */ return (controls(who, where) || (FLAGS(where) & LINK_OK)); #endif /* ABODE */ /*NOTREACHED*/ break; } return 0; } int can_link(dbref who, dbref what) { return (controls(who, what) || ((Typeof(what) == TYPE_EXIT) && DBFETCH(what)->sp.exit.ndest == 0)); } int could_doit(dbref player, dbref thing) { if(Typeof(thing) == TYPE_EXIT && DBFETCH(thing)->sp.exit.ndest == 0) { return 0; } return(eval_boolexp (player, DBFETCH(thing)->key, thing)); } int can_doit(dbref player, dbref thing, const char *default_fail_msg) { dbref loc; char buf[BUFFER_LEN]; if((loc = getloc(player)) == NOTHING) return 0; if(!could_doit(player, thing)) { /* can't do it */ if(get_attr(thing, "Fail")) { exec_or_notify(player, thing, get_attr(thing, "Fail")); } else if(default_fail_msg) { notify(player, default_fail_msg); } if(get_attr(thing, "Ofail") && !Dark(player)) { sprintf(buf, "%s %s", NAME(player), pronoun_substitute(player, get_attr(thing, "Ofail"), thing)); notify_except(DBFETCH(loc)->contents, player, buf); } if(get_attr(thing, "Afail")) { trigobj(thing,get_attr(thing, "Afail"),NOTHING); } return 0; } else { /* can do it */ if(get_attr(thing, "Succ")) { exec_or_notify(player, thing, get_attr(thing, "Succ")); } if(get_attr(thing, "Osucc") && !Dark(player)) { sprintf(buf, "%s %s", NAME(player), pronoun_substitute(player, get_attr(thing, "Osucc"), thing)); notify_except(DBFETCH(loc)->contents, player, buf); } if(get_attr(thing, "Asucc")) { trigobj(thing, get_attr(thing, "Asucc"), NOTHING); } return 1; } } int can_see(dbref player, dbref thing, int can_see_loc) { if (player == thing || Typeof(thing) == TYPE_EXIT || Typeof(thing) == TYPE_ROOM) return 0; if (can_see_loc) { switch (Typeof(thing)) { case TYPE_PROGRAM: return((FLAGS(thing) & LINK_OK) || controls(player, thing) || controls(player, DBFETCH(thing)->location)); default: return (!Dark(thing) || controls(player, thing)); } } else { /* can't see loc */ return player == OWNER(thing); } } int controls(dbref who, dbref what) { /* Wizard players control everything */ /* Wizard objects control everything except wizard players */ /* Architects control everything except wizard objects */ /* owners control their stuff */ /* objects (not players) with the same owner control each other */ /* No one controls garbage */ if (Typeof(what) == TYPE_GARBAGE) return 0; if(FLAGS(who)&QUELL) return 0; if(who == OWNER(what)) return 1; switch(Typeof(who)) { case TYPE_PLAYER: #ifdef GOD_PRIV if(is_god(who)) return 1; if(Wizard(who)) return (!is_god(what)); #else if(Wizard(who)) return 1; #endif /* GOD_PRIV */ if(Arch(who)) return (!(FLAGS(what)&WIZARD)); break; case TYPE_THING: if(Typeof(what) == TYPE_PLAYER) { if(Arch(who)) return (!(FLAGS(what)&WIZARD)); } else { if(what == OWNER(who)) return 0; if((OWNER(who) == OWNER(what)) && !(FLAGS(what)&WIZARD)) return 1; if(Wizard(who)) return 1; if(Arch(who)) return(!(FLAGS(what)&WIZARD)); } break; default: return 0; } return 0; } int restricted(dbref player, dbref thing, object_flag_type flag) { switch (flag) { case ARCHITECT: return (!Wizard(player) && (Typeof(thing) != TYPE_ROOM)); break; case DARK: return (!(Arch(player)) && (Typeof(thing) == TYPE_PLAYER)); /* no dark players. */ /*NOTREACHED*/ break; case MUCKER: return (!Wizard(player) && ((Typeof(thing) == TYPE_PROGRAM) || (Typeof(thing) == TYPE_PLAYER))); case BUILDER: return (!Wizard(player)); /*NOTREACHED*/ break; case WIZARD: if (Wizard(player) || God(player)) { if(player != global_cause || player != global_trigger) return 1; /* @force, or something similar */ #ifdef GOD_PRIV return ((Typeof(thing) == TYPE_PLAYER) && !God(player)); #else /* !GOD_PRIV */ return !Wizard(player); #endif /* GOD_PRIV */ } else return 1; /*NOTREACHED*/ break; case STICKY: return ((Typeof(thing)==TYPE_PROGRAM) && !(Arch(player) && Mucker(player))); break; default: return 0; /*NOTREACHED*/ break; } } int payfor(dbref who, int cost) { if(Arch(who)) { return 1; } else if(DBFETCH(who)->sp.player.pennies >= cost) { DBFETCH(who)->sp.player.pennies -= cost; DBDIRTY(who); return 1; } else { return 0; } } int word_start (const char *str, const char let) { int chk; for (chk = 1; *str; str++) { if (chk && *str == let) return 1; chk = *str == ' '; } return 0; } int ok_name(const char *name) { return (name && *name && *name != LOOKUP_TOKEN && *name != NUMBER_TOKEN && !index(name, ARG_DELIMITER) && !index(name, AND_TOKEN) && !index(name, OR_TOKEN) && !word_start(name, NOT_TOKEN) && string_compare(name, "me") && string_compare(name, "home") && string_compare(name, "here")); } int ok_player_name(const char *name) { const char *scan; if(!ok_name(name) || strlen(name) > PLAYER_NAME_LIMIT) return 0; for(scan = name; *scan; scan++) { if(!(isprint(*scan) && !isspace(*scan))) { /* was isgraph(*scan) */ return 0; } } /* lookup name to avoid conflicts */ return (lookup_player(name) == NOTHING); } int ok_password(const char *password) { const char *scan; if(*password == '\0') return 0; for(scan = password; *scan; scan++) { if(!(isprint(*scan) && !isspace(*scan))) { return 0; } } return 1; } int is_ok(dbref what) { if(what < 0) { return 0; } else { return(Typeof(what) != TYPE_GARBAGE); } } int Builder(dbref x) { return(Arch(x) || FLAGS(x)&BUILDER); } int Arch(dbref x) { return(Wizard(x) || ((Typeof(x) != TYPE_ROOM) && (FLAGS(x)&ARCHITECT && !(FLAGS(x)&QUELL)))); } int God(dbref x) { return is_god(x); } int Wizard(dbref x) { return (FLAGS(x)&WIZARD && !(FLAGS(x)&QUELL)); } int Mucker(dbref x) { return((Typeof(x) == TYPE_PLAYER) && (Wizard(x) || FLAGS(x)&MUCKER)); } int Murky(dbref x) { return(((Typeof(x) == TYPE_ROOM) || (Typeof(x) == TYPE_THING) || (Typeof(x) == TYPE_EXIT)) && FLAGS(x)&MUCKER); } char *check_func(const char *x) { return alloc_string (x); } #ifdef HAVEN int Haven(dbref x) {return FLAGS(x)&HAVEN;} #endif /* HAVEN */ int Halted(dbref x) { return FLAGS(x)&HALTED; } int Dark(dbref x) { if(Typeof(x) == TYPE_PLAYER && !notify_internal(x,NULL)) return 1; if((Typeof(x) != TYPE_ROOM) && (FLAGS(DBFETCH(x)->location)&DARK)) return 1; return (FLAGS(x)&DARK); } int Silent(dbref x) { return((Typeof(x) == TYPE_PLAYER) && (FLAGS(x)&STICKY)); } int Paranoid(dbref x) { return((Typeof(x) == TYPE_PLAYER) && (FLAGS(x)&PUPPET)); } #define MAX_FUN_ARGS 50 void do_switch(dbref player, char *arg1, char *arg2, dbref cause) { char *arg[MAX_FUN_ARGS], *ptrsrv[10]; char buff[BUFFER_LEN]; char *p; int x = 0, a = 0, any = 0; const char *delimit = ","; exec(&arg1, buff, player, cause, 0); arg[0] = alloc_ec_string(buff); for(x = 1; x < MAX_FUN_ARGS; x++) { arg[x] = NULL; p = (char *) parse_up(&arg2, delimit); if(p) arg[x] = alloc_ec_string(p); } if(!arg[1]) return; for(x = 0; x < 10; x++) ptrsrv[x] = wptr[x]; for(x = 1; x < (MAX_FUN_ARGS - 1) && arg[x] && arg[x + 1]; x += 2) if(wild_match(arg[x], arg[0])) { any = 1; for(a = 0; a < 10; a++) wptr[a] = ptrsrv[a]; trigobj(player, trash_braces(arg[x + 1]), cause); } if(x < MAX_FUN_ARGS && !any && arg[x]) { for(a = 0; a < 10; a++) wptr[a] = ptrsrv[a]; trigobj(player, trash_braces(arg[x]), cause); } }