/*
* flags.c - flag manipulation routines
*/
#include "copyright.h"
#include "config.h"
#include "db.h"
#include "mudconf.h"
#include "externs.h"
#include "command.h"
#include "flags.h"
#include "alloc.h"
#include "powers.h"
/**
* Sets or clears the indicated bit, no security checking.
* @param target The target object for setting/unsetting
* @param player The object who is setting/unsetting
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
int fh_any(dbref target, dbref player, FLAG flag, int fflags, int reset)
{
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;
} /* end fh_and() */
/**
* Function to block out non-GOD for setting or clearing a bit.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
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));
} /* end fh_god() */
/**
* Blocks out non-WIZARDS setting or clearing a bit.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
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));
} /* end fh_wiz() */
/**
* Only allows the bit to be set on players by WIZARDS.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
int fh_fixed(dbref target, dbref player, FLAG flag, int fflags, int reset)
{
if(isPlayer(target))
if(!Wizard(player) && !God(player))
return 0;
return (fh_any(target, player, flag, fflags, reset));
} /* end fh_fixed() */
/**
* Only allows WIZARDS, ROYALTY, (or GOD) to set or clear the bit.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
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));
} /* end fh_wizroy() */
/**
* Only allows players to set or clear this bit.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
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));
} /* end fh_inherit() */
/**
* Only allows GOD to set/clear this bit. Used for WIZARD flag.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
int fh_wiz_bit(dbref target, dbref player, FLAG flag, int fflags, int reset)
{
if(!God(player))
return 0;
if(God(target) && reset) {
notify(player, "You cannot make yourself mortal.");
return 0;
}
return (fh_any(target, player, flag, fflags, reset));
} /* end fh_wiz_bit() */
/**
* Manipulates the dark bit. Non-Wizards may not set on players.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
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));
} /* end fh_dark_bit() */
/**
* Manipulates the going bit.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
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;
return (fh_any(target, player, flag, fflags, reset));
} /* end fh_going_bit() */
/**
* Sets or clears bits that affect hearing.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
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;
} /* end fh_hear_bit() */
/**
* Sets or clears bits that affect xcode in glue.h.
* @param target Target object for setting/unsetting
* @param player The object that is setting/unsetting
* @param flag The flag to be manipulated
* @param fflags ??
* @param reset If 1, we're resetting the flag
*/
int fh_xcode_bit(dbref target, dbref player, FLAG flag, int fflags, int reset)
{
int got_xcode;
int new_xcode;
got_xcode = Hardcode(target);
fh_wiz(target, player, flag, fflags, reset);
new_xcode = Hardcode(target);
handle_xcode(player, target, got_xcode, new_xcode);
return 1;
} /* end fh_xcode_bit() */
/**
* Alphabetized flag listing
* 0 = Flag's visible name
* 1 = Flag's bit representation
* 2 = Flag's letter alias
* 3 = Flag's wordspace
* 4 = Who may see the flag (0 = all)
* 5 = Permissions
*/
FLAGENT gen_flags[] = {
{"ABODE", ABODE, 'A',
FLAG_WORD2, 0, fh_any}
,
{"ANSI", ANSI, 'X',
FLAG_WORD2, 0, fh_any}
,
{"ANSIMAP", ANSIMAP, 'P',
FLAG_WORD2, 0, fh_any}
,
{"AUDIBLE", HEARTHRU, 'a',
0, 0, fh_hear_bit}
,
{"AUDITORIUM", AUDITORIUM, 'b',
FLAG_WORD2, 0, fh_any}
,
{"COMPRESS", COMPRESS, '.',
FLAG_WORD2, 0, fh_any}
,
{"CONNECTED", CONNECTED, 'c',
FLAG_WORD2, CA_NO_DECOMP, fh_god}
,
{"CHOWN_OK", CHOWN_OK, 'C',
0, 0, fh_any}
,
{"DARK", DARK, 'D',
0, 0, fh_dark_bit}
,
{"DESTROY_OK", DESTROY_OK, 'd',
0, 0, fh_any}
,
{"ENTER_OK", ENTER_OK, 'e',
0, 0, fh_any}
,
{"FIXED", FIXED, 'f',
FLAG_WORD2, 0, fh_fixed}
,
{"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}
,
{"HALTED", HALT, 'h',
0, 0, fh_any}
,
{"HAS_DAILY", HAS_DAILY, '*',
FLAG_WORD2, CA_GOD | CA_NO_DECOMP, fh_god}
,
{"HAS_FORWARDLIST", HAS_FWDLIST, '&',
FLAG_WORD2, CA_GOD | CA_NO_DECOMP, fh_god}
,
{"HAS_HOURLY", HAS_HOURLY, '*',
FLAG_WORD2, CA_GOD | CA_NO_DECOMP, fh_god}
,
{"HAS_LISTEN", HAS_LISTEN, '@',
FLAG_WORD2, CA_GOD | CA_NO_DECOMP, fh_god}
,
{"HAS_STARTUP", HAS_STARTUP, '+',
0, CA_GOD | CA_NO_DECOMP, fh_god}
,
{"HAVEN", HAVEN, 'H',
0, 0, fh_any}
,
{"HEAD", HEAD_FLAG, '?',
FLAG_WORD2, 0, fh_wiz}
,
{"BLIND", BLIND, '(',
FLAG_WORD2, 0, fh_any}
,
{"IMMORTAL", IMMORTAL, 'i',
0, 0, fh_wiz}
,
{"IN_CHARACTER", IN_CHARACTER, '#',
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}
,
{"LIGHT", LIGHT, 'l',
FLAG_WORD2, 0, fh_any}
,
{"LINK_OK", LINK_OK, 'L',
0, 0, fh_any}
,
{"MONITOR", MONITOR, 'M',
0, 0, fh_hear_bit}
,
{"MULTIOK", MULTIOK, 'y',
FLAG_WORD2, CA_WIZARD, fh_wiz}
,
{"MYOPIC", MYOPIC, 'm',
0, 0, fh_any}
,
{"NOBLEED", NOBLEED, '-',
FLAG_WORD2, 0, fh_any}
,
{"NO_COMMAND", NO_COMMAND, 'n',
FLAG_WORD2, 0, fh_any}
,
{"NOSPOOF", NOSPOOF, 'N',
0, 0, fh_any}
,
{"OPAQUE", OPAQUE, 'O',
0, 0, fh_any}
,
{"PARENT_OK", PARENT_OK, 'Y',
FLAG_WORD2, 0, fh_any}
,
{"PLAYER_MAILS", PLAYER_MAILS, 'B',
FLAG_WORD2, CA_GOD | CA_NO_DECOMP, fh_god}
,
{"PUPPET", PUPPET, 'p',
0, 0, fh_hear_bit}
,
{"QUIET", QUIET, 'Q',
0, 0, fh_any}
,
{"ROBOT", ROBOT, 'r',
0, 0, fh_any}
,
{"ROYALTY", ROYALTY, 'Z',
0, 0, fh_wiz}
,
{"SAFE", SAFE, 's',
0, 0, fh_any}
,
{"SLAVE", SLAVE, 'x',
FLAG_WORD2, CA_WIZARD, fh_wiz}
,
{"STAFF", STAFF, 'w',
FLAG_WORD2, 0, fh_wiz}
,
{"STICKY", STICKY, 'S',
0, 0, fh_wiz}
,
{"SUSPECT", SUSPECT, 'u',
FLAG_WORD2, CA_WIZARD, fh_wiz}
,
{"TERSE", TERSE, 'q',
0, 0, fh_any}
,
{"TRACE", TRACE, 'T',
0, 0, fh_any}
,
{"TRANSPARENT", SEETHRU, 't',
0, 0, fh_any}
,
{"UNFINDABLE", UNFINDABLE, 'U',
FLAG_WORD2, 0, fh_any}
,
{"UNINSPECTED", UNINSPECTED, 'g',
FLAG_WORD2, 0, fh_wizroy}
,
{"VERBOSE", VERBOSE, 'v',
0, 0, fh_any}
,
{"VISUAL", VISUAL, 'V',
0, 0, fh_any}
,
{"VACATION", VACATION, '|',
FLAG_WORD2, 0, fh_fixed}
,
{"WIZARD", WIZARD, 'W',
0, 0, fh_wiz_bit}
,
{"XCODE", HARDCODE, 'X',
FLAG_WORD2, 0, fh_xcode_bit}
,
{"ZOMBIE", ZOMBIE, 'z',
FLAG_WORD2, CA_WIZARD, fh_wiz}
,
{NULL, 0, ' ',
0, 0, NULL}
};
/**
* Listing of valid object types
*/
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}
};
/**
* Initializes flag hash tables.
*/
void init_flagtab(void)
{
FLAGENT *fp;
char *nbuf, *np, *bp;
hashinit(&mudstate.flags_htab, 100 * HASH_FACTOR);
nbuf = alloc_sbuf("init_flagtab");
for(fp = gen_flags; fp->flagname; fp++) {
for(np = nbuf, bp = (char *) fp->flagname; *bp; np++, bp++)
*np = ToLower(*bp);
*np = '\0';
hashadd(nbuf, (int *) fp, &mudstate.flags_htab);
}
free_sbuf(nbuf);
} /* end init_flagtab() */
/**
* Displays available flags. Used in @list 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);
} /* end display_flagtab() */
/**
* ??
*/
FLAGENT *find_flag(dbref thing, char *flagname)
{
char *cp;
/* Make sure the flag name is valid */
for(cp = flagname; *cp; cp++)
*cp = ToLower(*cp);
return (FLAGENT *) hashfind(flagname, &mudstate.flags_htab);
} /* end find_flag() */
/**
* Sets or clears a specified flag on an object.
* @param target Target object
* @param player The object doing the setting
* @paran flag The flag being set/unset
* @param key Are we @set/quiet'in?
*/
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 (*flag && isspace(*flag))
flag++;
if(*flag == '!') {
negate = 1;
flag++;
}
while (*flag && isspace(*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_printf(player, "%s - %s %s", Name(target), fp->flagname,
negate ? "cleared." : "set.");
return;
} /* end flag_set() */
/**
* Converts a flags word into corresponding letters.
* @param player The invoking object
* @param flagword ??
* @param flag2word ??
* @param flag3word ??
*/
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((flagtype == TYPE_PLAYER) && (fp->flagvalue == CONNECTED)
&& ((flagword & (WIZARD | DARK)) == (WIZARD | DARK)) &&
!Wizard(player))
continue;
safe_sb_chr(fp->flaglett, buf, &bp);
}
}
*bp = '\0';
return buf;
} /* end decode_flags() */
/**
* Does object have flag visible to player?
* @param player The player we're looking for
* @param target The object with the flag
* @param flagname The flag in question
*/
int has_flag(dbref player, dbref target, char *flagname)
{
FLAGENT *fp;
FLAG fv;
fp = find_flag(target, flagname);
if(fp == NULL)
return 0;
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))
return 0;
if((fp->listperm & CA_GOD) && !God(player))
return 0;
/*
* don't show CONNECT on dark wizards to mortals
*/
if(isPlayer(target) && (fp->flagvalue == CONNECTED) &&
((Flags(target) & (WIZARD | DARK)) == (WIZARD | DARK)) &&
!Wizard(player))
return 0;
return 1;
}
return 0;
} /* end has_flag() */
/**
* Returns an mbuf containing the type and flags on thing.
* @param player The player to send to
* @param target The object whose flags we're checking
*/
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) &&
((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;
} /* end flag_description() */
/**
* Returns an lbuf containing the name and number of an object.
* @param target The target object
*/
char *unparse_object_numonly(dbref target)
{
char *buf;
buf = alloc_lbuf("unparse_object_numonly");
if(target == NOTHING) {
StringCopy(buf, "*NOTHING*");
} else if(target == HOME) {
StringCopy(buf, "*HOME*");
} else if(!Good_obj(target)) {
sprintf(buf, "*ILLEGAL*(#%d)", target);
} else {
sprintf(buf, "%s(#%d)", Name(target), target);
}
return buf;
} /* end unparse_object_numonly() */
/**
* Returns 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 == NOTHING) {
StringCopy(buf, "*NOTHING*");
} else if(target == HOME) {
StringCopy(buf, "*HOME*");
} 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%s)", Name(target), target,
*fp ? ":" : "", fp);
free_sbuf(fp);
} else {
/*
* show only the name.
*/
StringCopy(buf, Name(target));
}
}
return buf;
} /* end unparse_object() */
/**
* Converts a list of flag letters into its bit pattern.
* Also set the type qualifier if specified and not already set.
* @param player The evoking object
* @param flaglist The list of flags to conver to bit pattern
* @param fset ??
* @param p_type ??
*/
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_printf(player,
"%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_printf(player,
"%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;
} /* end convert_flags() */
/**
* Produces commands to set flags on target.
* @param player The evoking object
* @param thing The target object
* @param thingname ??
*/
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_printf(player, "@set %s=%s", strip_ansi(thingname),
fp->flagname);
}
} /* end decompile_flags() */