// flags.cpp - flag manipulation routines. // // $Id: flags.cpp,v 1.6 2000/08/09 07:03:20 sdennis Exp $ // #include "copyright.h" #include "autoconf.h" #include "config.h" #include "externs.h" #include "db.h" #include "mudconf.h" #include "command.h" #include "flags.h" #include "alloc.h" #include "powers.h" extern void FDECL(cf_log_notfound, (dbref, char *, const char *, char *)); #ifndef STANDALONE /* * --------------------------------------------------------------------------- * * fh_any: set or clear indicated bit, no security checking */ int fh_any(dbref target, dbref player, FLAG flag, int fflags, int reset) { // Never let God drop his/her own wizbit. // if ( God(target) && reset && (flag == WIZARD) && !(fflags & FLAG_WORD2) && !(fflags & FLAG_WORD3)) { notify(player, "You cannot make God mortal."); return 0; } // Otherwise we can go do it. // if (fflags & FLAG_WORD3) { if (reset) s_Flags3(target, Flags3(target) & ~flag); else s_Flags3(target, Flags3(target) | flag); } else if (fflags & FLAG_WORD2) { if (reset) s_Flags2(target, Flags2(target) & ~flag); else s_Flags2(target, Flags2(target) | flag); } else { if (reset) s_Flags(target, Flags(target) & ~flag); else s_Flags(target, Flags(target) | flag); } return 1; } /* * --------------------------------------------------------------------------- * * fh_god: only GOD may set or clear the bit */ int fh_god(dbref target, dbref player, FLAG flag, int fflags, int reset) { if (!God(player)) return 0; return (fh_any(target, player, flag, fflags, reset)); } /* * --------------------------------------------------------------------------- * * fh_wiz: only WIZARDS (or GOD) may set or clear the bit */ int fh_wiz(dbref target, dbref player, FLAG flag, int fflags, int reset) { if (!Wizard(player) && !God(player)) return 0; return (fh_any(target, player, flag, fflags, reset)); } /* * --------------------------------------------------------------------------- * * fh_wizroy: only WIZARDS, ROYALTY, (or GOD) may set or clear the bit */ int fh_wizroy(dbref target, dbref player, FLAG flag, int fflags, int reset) { if (!WizRoy(player) && !God(player)) return 0; return (fh_any(target, player, flag, fflags, reset)); } /* * --------------------------------------------------------------------------- * * fh_restrict_player (renamed from fh_fixed): Only Wizards can set * * this on players, but ordinary players can set it on other types * * of objects. */ int fh_restrict_player ( dbref target, dbref player, FLAG flag, int fflags, int reset ) { if ( isPlayer(target) && !Wizard(player) && !God(player)) { return 0; } return fh_any(target, player, flag, fflags, reset); } /* --------------------------------------------------------------------------- * fh_privileged: You can set this flag on a non-player object, if you * yourself have this flag and are a player who owns themselves (i.e., * no robots). Only God can set this on a player. */ int fh_privileged ( dbref target, dbref player, FLAG flag, int fflags, int reset ) { int has_it; if (!God(player)) { if (!isPlayer(player) || (player != Owner(player))) { return 0; } if (isPlayer(target)) { return 0; } if (fflags & FLAG_WORD3) { has_it = (Flags3(player) & flag) ? 1 : 0; } else if (fflags & FLAG_WORD2) { has_it = (Flags2(player) & flag) ? 1 : 0; } else { has_it = (Flags(player) & flag) ? 1 : 0; } if (!has_it) { return 0; } } return fh_any(target, player, flag, fflags, reset); } /* * --------------------------------------------------------------------------- * * fh_inherit: only players may set or clear this bit. */ int fh_inherit(dbref target, dbref player, FLAG flag, int fflags, int reset) { if (!Inherits(player)) return 0; return (fh_any(target, player, flag, fflags, reset)); } /* * --------------------------------------------------------------------------- * * fh_dark_bit: manipulate the dark bit. Nonwizards may not set on players. */ int fh_dark_bit(dbref target, dbref player, FLAG flag, int fflags, int reset) { if ( !reset && isPlayer(target) && !( (target == player) && Can_Hide(player)) && !Wizard(player) && !God(player)) { return 0; } return fh_any(target, player, flag, fflags, reset); } /* * --------------------------------------------------------------------------- * * fh_going_bit: manipulate the going bit. Non-gods may only clear on rooms. */ int fh_going_bit(dbref target, dbref player, FLAG flag, int fflags, int reset) { if ( Going(target) && reset && (Typeof(target) != TYPE_GARBAGE)) { notify(player, "Your object has been spared from destruction."); return fh_any(target, player, flag, fflags, reset); } if (!God(player)) { return 0; } // Even God should not be allowed set protected dbrefs GOING. // if ( !reset && ( target == 0 || target == God(target) || target == mudconf.start_home || target == mudconf.start_room || target == mudconf.default_home || target == mudconf.master_room)) { return 0; } return fh_any(target, player, flag, fflags, reset); } /* * --------------------------------------------------------------------------- * * fh_hear_bit: set or clear bits that affect hearing. */ int fh_hear_bit(dbref target, dbref player, FLAG flag, int fflags, int reset) { int could_hear; if (isPlayer(target) && (flag & MONITOR)) { if (Can_Monitor(player)) fh_any(target, player, flag, fflags, reset); else return 0; } could_hear = Hearer(target); fh_any(target, player, flag, fflags, reset); handle_ears(target, could_hear, Hearer(target)); return 1; } /* --------------------------------------------------------------------------- * fh_player_bit: Can set and reset this on everything but players. */ int fh_player_bit ( dbref target, dbref player, FLAG flag, int fflags, int reset ) { if (isPlayer(target)) { return 0; } return fh_any(target, player, flag, fflags, reset); } /* --------------------------------------------------------------------------- * fh_staff: only STAFF, WIZARDS, ROYALTY, (or GOD) may set or clear * the bit. */ int fh_staff ( dbref target, dbref player, FLAG flag, int fflags, int reset ) { if (!Staff(player) && !God(player)) return 0; return (fh_any(target, player, flag, fflags, reset)); } FLAGENT gen_flags[] = { {"ABODE", ABODE, 'A', FLAG_WORD2, 0, fh_any}, {"ANSI", ANSI, 'X', FLAG_WORD2, 0, fh_any}, {"AUDITORIUM", AUDITORIUM, 'b', FLAG_WORD2, 0, fh_any}, {"COMPRESS", COMPRESS, '.', FLAG_WORD2, 0, fh_any}, {"CHOWN_OK", CHOWN_OK, 'C', 0, 0, fh_any}, {"HAS_DAILY", HAS_DAILY, '*', FLAG_WORD2, CA_GOD|CA_NO_DECOMP, fh_god}, {"PLAYER_MAILS", PLAYER_MAILS, 'B', FLAG_WORD2, CA_GOD|CA_NO_DECOMP, fh_god}, {"DARK", DARK, 'D', 0, 0, fh_dark_bit}, {"FLOATING", FLOATING, 'F', FLAG_WORD2, 0, fh_any}, {"GAGGED", GAGGED, 'j', FLAG_WORD2, 0, fh_wiz}, {"GOING", GOING, 'G', 0, CA_NO_DECOMP, fh_going_bit}, {"HAVEN", HAVEN, 'H', 0, 0, fh_any}, {"HEAD", HEAD_FLAG, '?', FLAG_WORD2, 0, fh_wiz}, {"INHERIT", INHERIT, 'I', 0, 0, fh_inherit}, {"JUMP_OK", JUMP_OK, 'J', 0, 0, fh_any}, {"KEY", KEY, 'K', FLAG_WORD2, 0, fh_any}, {"LINK_OK", LINK_OK, 'L', 0, 0, fh_any}, {"MONITOR", MONITOR, 'M', 0, 0, fh_hear_bit}, {"NOSPOOF", NOSPOOF, 'N', 0, 0, fh_any}, {"OPAQUE", TM_OPAQUE, 'O', 0, 0, fh_any}, {"QUIET", QUIET, 'Q', 0, 0, fh_any}, {"STAFF", STAFF, 'w', FLAG_WORD2, 0, fh_wiz}, {"STICKY", STICKY, 'S', 0, 0, fh_any}, {"TRACE", TRACE, 'T', 0, 0, fh_any}, {"UNFINDABLE", UNFINDABLE, 'U', FLAG_WORD2, 0, fh_any}, {"VISUAL", VISUAL, 'V', 0, 0, fh_any}, {"VACATION", VACATION, '|', FLAG_WORD2, 0, fh_restrict_player}, {"WIZARD", WIZARD, 'W', 0, 0, fh_god}, {"PARENT_OK", PARENT_OK, 'Y', FLAG_WORD2, 0, fh_any}, {"ROYALTY", ROYALTY, 'Z', 0, 0, fh_wiz}, {"FIXED", FIXED, 'f', FLAG_WORD2, 0, fh_restrict_player}, {"UNINSPECTED", UNINSPECTED, 'g', FLAG_WORD2, 0, fh_wizroy}, {"NO_COMMAND", NO_COMMAND, 'n', FLAG_WORD2, 0, fh_any}, {"NOBLEED", NOBLEED, '-', FLAG_WORD2, 0, fh_any}, {"AUDIBLE", HEARTHRU, 'a', 0, 0, fh_hear_bit}, {"CONNECTED", CONNECTED, 'c', FLAG_WORD2, CA_NO_DECOMP, fh_god}, {"DESTROY_OK", DESTROY_OK, 'd', 0, 0, fh_any}, {"ENTER_OK", ENTER_OK, 'e', 0, 0, fh_any}, {"HALTED", HALT, 'h', 0, 0, fh_any}, {"IMMORTAL", IMMORTAL, 'i', 0, 0, fh_wiz}, {"LIGHT", LIGHT, 'l', FLAG_WORD2, 0, fh_any}, {"MYOPIC", MYOPIC, 'm', 0, 0, fh_any}, {"PUPPET", PUPPET, 'p', 0, 0, fh_hear_bit}, {"TERSE", TERSE, 'q', 0, 0, fh_any}, {"ROBOT", ROBOT, 'r', 0, 0, fh_player_bit}, {"SAFE", SAFE, 's', 0, 0, fh_any}, {"TRANSPARENT", SEETHRU, 't', 0, 0, fh_any}, {"SUSPECT", SUSPECT, 'u', FLAG_WORD2, CA_WIZARD, fh_wiz}, {"VERBOSE", VERBOSE, 'v', 0, 0, fh_any}, {"SLAVE", SLAVE, 'x', FLAG_WORD2, CA_WIZARD, fh_wiz}, {"HAS_STARTUP", HAS_STARTUP, '+', 0, CA_GOD|CA_NO_DECOMP, fh_god}, {"HAS_FORWARDLIST", HAS_FWDLIST, '&', FLAG_WORD2, CA_GOD|CA_NO_DECOMP, fh_god}, {"HAS_LISTEN", HAS_LISTEN, '@', FLAG_WORD2, CA_GOD|CA_NO_DECOMP, fh_god}, {"HTML", HTML, '(', FLAG_WORD2, 0, fh_any}, #ifdef WOD_REALMS {"OBF", OBF, 'o', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"HSS", HSS, 'k', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"UMBRA", UMBRA, 'y', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"SHROUD", SHROUD, '$', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"MATRIX", MATRIX, '/', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"MEDIUM", MEDIUM, '^', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"DEAD", DEAD, '_', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"FAE", FAE, '0', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"CHIMERA", CHIMERA, '1', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, {"PEERING", PEERING, '2', FLAG_WORD3, CA_ADMIN|CA_STAFF, fh_wizroy}, #endif { NULL, 0, ' ', 0, 0, NULL} }; #endif /* STANDALONE */ OBJENT object_types[8] = { {"ROOM", 'R', CA_PUBLIC, OF_CONTENTS|OF_EXITS|OF_DROPTO|OF_HOME}, {"THING", ' ', CA_PUBLIC, OF_CONTENTS|OF_LOCATION|OF_EXITS|OF_HOME|OF_SIBLINGS}, {"EXIT", 'E', CA_PUBLIC, OF_SIBLINGS}, {"PLAYER", 'P', CA_PUBLIC, OF_CONTENTS|OF_LOCATION|OF_EXITS|OF_HOME|OF_OWNER|OF_SIBLINGS}, {"TYPE5", '+', CA_GOD, 0}, {"GARBAGE", '-', CA_PUBLIC, OF_CONTENTS|OF_LOCATION|OF_EXITS|OF_HOME|OF_SIBLINGS}, {"GARBAGE", '#', CA_GOD, 0} }; #ifndef STANDALONE /* * --------------------------------------------------------------------------- * * init_flagtab: initialize flag hash tables. */ void NDECL(init_flagtab) { char *nbuf = alloc_sbuf("init_flagtab"); for (FLAGENT *fp = gen_flags; fp->flagname; fp++) { strncpy(nbuf, fp->flagname, SBUF_SIZE); nbuf[SBUF_SIZE-1] = '\0'; _strlwr(nbuf); hashaddLEN(nbuf, strlen(nbuf), (int *)fp, &mudstate.flags_htab); } free_sbuf(nbuf); } /* * --------------------------------------------------------------------------- * * display_flags: display available flags. */ void display_flagtab(dbref player) { char *buf, *bp; FLAGENT *fp; bp = buf = alloc_lbuf("display_flagtab"); safe_str((char *)"Flags:", buf, &bp); for (fp = gen_flags; fp->flagname; fp++) { if ((fp->listperm & CA_WIZARD) && !Wizard(player)) continue; if ((fp->listperm & CA_GOD) && !God(player)) continue; safe_chr(' ', buf, &bp); safe_str((char *)fp->flagname, buf, &bp); safe_chr('(', buf, &bp); safe_chr(fp->flaglett, buf, &bp); safe_chr(')', buf, &bp); } *bp = '\0'; notify(player, buf); free_lbuf(buf); } char *MakeCanonicalFlagName ( const char *pName, int *pnName, BOOL *pbValid ) { static char buff[SBUF_SIZE]; char *p = buff; int nName = 0; while (*pName && nName < SBUF_SIZE) { *p = Tiny_ToLower[(unsigned char)*pName]; p++; pName++; nName++; } *p = '\0'; if (nName < SBUF_SIZE) { *pnName = nName; *pbValid = TRUE; return buff; } else { *pnName = 0; *pbValid = FALSE; return NULL; } } FLAGENT *find_flag(dbref thing, char *flagname) { // Convert flagname to canonical lowercase format. // int nName; BOOL bValid; char *pName = MakeCanonicalFlagName(flagname, &nName, &bValid); FLAGENT *fe = NULL; if (bValid) { fe = (FLAGENT *)hashfindLEN(pName, nName, &mudstate.flags_htab); } return fe; } /* * --------------------------------------------------------------------------- * * flag_set: Set or clear a specified flag on an object. */ void flag_set(dbref target, dbref player, char *flag, int key) { FLAGENT *fp; int negate, result; /* * Trim spaces, and handle the negation character */ negate = 0; while (Tiny_IsSpace[(unsigned char)*flag]) flag++; if (*flag == '!') { negate = 1; flag++; } while (Tiny_IsSpace[(unsigned char)*flag]) flag++; // Make sure a flag name was specified. // if (*flag == '\0') { if (negate) notify(player, "You must specify a flag to clear."); else notify(player, "You must specify a flag to set."); return; } fp = find_flag(target, flag); if (fp == NULL) { notify(player, "I don't understand that flag."); return; } /* * Invoke the flag handler, and print feedback */ result = fp->handler(target, player, fp->flagvalue, fp->flagflag, negate); if (!result) notify(player, "Permission denied."); else if (!(key & SET_QUIET) && !Quiet(player)) notify(player, (negate ? "Cleared." : "Set.")); return; } /* * --------------------------------------------------------------------------- * * decode_flags: converts a flags word into corresponding letters. */ char *decode_flags(dbref player, FLAG flagword, FLAG flag2word, FLAG flag3word) { char *buf, *bp; FLAGENT *fp; int flagtype; FLAG fv; buf = bp = alloc_sbuf("decode_flags"); *bp = '\0'; if (!Good_obj(player)) { StringCopy(buf, "#-2 ERROR"); return buf; } flagtype = (flagword & TYPE_MASK); if (object_types[flagtype].lett != ' ') { safe_sb_chr(object_types[flagtype].lett, buf, &bp); } for (fp = gen_flags; fp->flagname; fp++) { if (fp->flagflag & FLAG_WORD3) { fv = flag3word; } else if (fp->flagflag & FLAG_WORD2) { fv = flag2word; } else { fv = flagword; } if (fv & fp->flagvalue) { if ((fp->listperm & CA_WIZARD) && !Wizard(player)) { continue; } if ((fp->listperm & CA_GOD) && !God(player)) { continue; } // Don't show CONNECT on dark wizards to mortals // if ( isPlayer(player) && (fp->flagvalue == CONNECTED) && (fp->flagflag & FLAG_WORD2) && ((flagword & (WIZARD | DARK)) == (WIZARD | DARK)) && !Wizard(player)) { continue; } safe_sb_chr(fp->flaglett, buf, &bp); } } *bp = '\0'; return buf; } /* * --------------------------------------------------------------------------- * * has_flag: does object have flag visible to player? */ int has_flag(dbref player, dbref it, char *flagname) { FLAGENT *fp = find_flag(it, flagname); if (!fp) { return 0; } FLAG fv; if (fp->flagflag & FLAG_WORD3) { fv = Flags3(it); } else if (fp->flagflag & FLAG_WORD2) { fv = Flags2(it); } else { fv = Flags(it); } if (fv & fp->flagvalue) { if ((fp->listperm & CA_WIZARD) && !Wizard(player)) { return 0; } if ((fp->listperm & CA_GOD) && !God(player)) { return 0; } // Don't show CONNECT on dark wizards to mortals // if ( isPlayer(it) && (fp->flagvalue == CONNECTED) && (fp->flagflag & FLAG_WORD2) && ((Flags(it) & (WIZARD | DARK)) == (WIZARD | DARK)) && !Wizard(player)) { return 0; } return 1; } return 0; } /* * --------------------------------------------------------------------------- * * flag_description: Return an mbuf containing the type and flags on thing. */ char *flag_description(dbref player, dbref target) { char *buff, *bp; FLAGENT *fp; int otype; FLAG fv; // Allocate the return buffer. // otype = Typeof(target); bp = buff = alloc_mbuf("flag_description"); // Store the header strings and object type. // safe_mb_str((char *)"Type: ", buff, &bp); safe_mb_str((char *)object_types[otype].name, buff, &bp); safe_mb_str((char *)" Flags:", buff, &bp); if (object_types[otype].perm != CA_PUBLIC) { *bp = '\0'; return buff; } // Store the type-invariant flags. // for (fp = gen_flags; fp->flagname; fp++) { if (fp->flagflag & FLAG_WORD3) fv = Flags3(target); else if (fp->flagflag & FLAG_WORD2) fv = Flags2(target); else fv = Flags(target); if (fv & fp->flagvalue) { if ((fp->listperm & CA_WIZARD) && !Wizard(player)) continue; if ((fp->listperm & CA_GOD) && !God(player)) continue; /* * don't show CONNECT on dark wizards to mortals */ if ( isPlayer(target) && (fp->flagvalue == CONNECTED) && (fp->flagflag & FLAG_WORD2) && ((Flags(target) & (WIZARD | DARK)) == (WIZARD | DARK)) && !Wizard(player)) { continue; } safe_mb_chr(' ', buff, &bp); safe_mb_str((char *)fp->flagname, buff, &bp); } } // Terminate the string, and return the buffer to the caller. // *bp = '\0'; return buff; } /* * --------------------------------------------------------------------------- * * Return an lbuf containing the name and number of an object */ char *unparse_object_numonly(dbref target) { char *buf; buf = alloc_lbuf("unparse_object_numonly"); if (target < 0) { strcpy(buf, aszSpecialDBRefNames[-target]); } else if (!Good_obj(target)) { sprintf(buf, "*ILLEGAL*(#%d)", target); } else { sprintf(buf, "%s(#%d)", Name(target), target); } return buf; } /* * --------------------------------------------------------------------------- * * Return an lbuf pointing to the object name and possibly the db# and flags */ char *unparse_object(dbref player, dbref target, int obey_myopic) { char *buf, *fp; int exam; buf = alloc_lbuf("unparse_object"); if (target < 0) { strcpy(buf, aszSpecialDBRefNames[-target]); } else if (!Good_obj(target)) { sprintf(buf, "*ILLEGAL*(#%d)", target); } else { if (obey_myopic) { exam = MyopicExam(player, target); } else { exam = Examinable(player, target); } if ( exam || (Flags(target) & (CHOWN_OK | JUMP_OK | LINK_OK | DESTROY_OK)) || (Flags2(target) & ABODE)) { // show everything // fp = unparse_flags(player, target); sprintf(buf, "%s(#%d%s)", Name(target), target, fp); free_sbuf(fp); } else { // show only the name. // strcpy(buf, Name(target)); } } return buf; } /* --------------------------------------------------------------------------- * cf_flag_access: Modify who can set a flag. */ CF_HAND(cf_flag_access) { TINY_STRTOK_STATE tts; Tiny_StrTokString(&tts, str); Tiny_StrTokControl(&tts, " \t=,"); char *fstr = Tiny_StrTokParse(&tts); char *permstr = Tiny_StrTokParse(&tts); if (!fstr || !*fstr) { return -1; } FLAGENT *fp; if ((fp = find_flag(GOD, fstr)) == NULL) { cf_log_notfound(player, cmd, "No such flag", fstr); return -1; } // Don't change the handlers on special things. // if ( (fp->handler != fh_any) && (fp->handler != fh_wizroy) && (fp->handler != fh_wiz) && (fp->handler != fh_god) && (fp->handler != fh_restrict_player) && (fp->handler != fh_privileged)) { STARTLOG(LOG_CONFIGMODS, "CFG", "PERM"); log_text((char *) "Cannot change access for flag: "); log_text((char *) fp->flagname); ENDLOG; return -1; } if (!strcmp(permstr, (char *) "any")) { fp->handler = fh_any; } else if (!strcmp(permstr, (char *) "royalty")) { fp->handler = fh_wizroy; } else if (!strcmp(permstr, (char *) "wizard")) { fp->handler = fh_wiz; } else if (!strcmp(permstr, (char *) "god")) { fp->handler = fh_god; } else if (!strcmp(permstr, (char *) "restrict_player")) { fp->handler = fh_restrict_player; } else if (!strcmp(permstr, (char *) "privileged")) { fp->handler = fh_privileged; } else if (!strcmp(permstr, (char *) "staff")) { fp->handler = fh_staff; } else { cf_log_notfound(player, cmd, "Flag access", permstr); return -1; } return 0; } /* * --------------------------------------------------------------------------- * * convert_flags: convert a list of flag letters into its bit pattern. * * Also set the type qualifier if specified and not already set. */ int convert_flags(dbref player, char *flaglist, FLAGSET *fset, FLAG *p_type) { int i, handled; char *s; FLAG flag1mask, flag2mask, flag3mask, type; FLAGENT *fp; flag1mask = flag2mask = flag3mask = 0; type = NOTYPE; for (s = flaglist; *s; s++) { handled = 0; /* * Check for object type */ for (i = 0; (i <= 7) && !handled; i++) { if ((object_types[i].lett == *s) && !(((object_types[i].perm & CA_WIZARD) && !Wizard(player)) || ((object_types[i].perm & CA_GOD) && !God(player)))) { if ((type != NOTYPE) && (type != i)) { notify(player, tprintf("%c: Conflicting type specifications.", *s)); return 0; } type = i; handled = 1; } } /* * Check generic flags */ if (handled) continue; for (fp = gen_flags; (fp->flagname) && !handled; fp++) { if ((fp->flaglett == *s) && !(((fp->listperm & CA_WIZARD) && !Wizard(player)) || ((fp->listperm & CA_GOD) && !God(player)))) { if (fp->flagflag & FLAG_WORD3) flag3mask |= fp->flagvalue; else if (fp->flagflag & FLAG_WORD2) flag2mask |= fp->flagvalue; else flag1mask |= fp->flagvalue; handled = 1; } } if (!handled) { notify(player, tprintf("%c: Flag unknown or not valid for specified object type", *s)); return 0; } } /* * return flags to search for and type */ (*fset).word1 = flag1mask; (*fset).word2 = flag2mask; (*fset).word3 = flag3mask; *p_type = type; return 1; } /* * --------------------------------------------------------------------------- * * decompile_flags: Produce commands to set flags on target. */ void decompile_flags(dbref player, dbref thing, char *thingname) { FLAG f1, f2, f3; FLAGENT *fp; /* * Report generic flags */ f1 = Flags(thing); f2 = Flags2(thing); f3 = Flags3(thing); for (fp = gen_flags; fp->flagname; fp++) { /* * Skip if we shouldn't decompile this flag */ if (fp->listperm & CA_NO_DECOMP) continue; /* * Skip if this flag is not set */ if (fp->flagflag & FLAG_WORD3) { if (!(f3 & fp->flagvalue)) continue; } else if (fp->flagflag & FLAG_WORD2) { if (!(f2 & fp->flagvalue)) continue; } else { if (!(f1 & fp->flagvalue)) continue; } /* * Skip if we can't see this flag */ if (!check_access(player, fp->listperm)) continue; /* * We made it this far, report this flag */ notify(player, tprintf("@set %s=%s", strip_ansi(thingname), fp->flagname)); } } #endif /* * STANDALONE */