Skip to content

Commit

Permalink
Merge pull request #718 from wyld-sw/mfn-flag
Browse files Browse the repository at this point in the history
Add {flag?} MPI function
  • Loading branch information
tanabi authored Jan 15, 2024
2 parents bb00824 + 66d515f commit 402d60d
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 163 deletions.
25 changes: 25 additions & 0 deletions include/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -2194,6 +2194,18 @@ int member(dbref thing, dbref list);
*/
dbref new_object(bool isplayer);

/**
* Returns true if the object has the given flag set (or reset).
*
* Understands flag alias and multiple not conditions (!!x = x, !!!x = !x).
*
* Checking "truewizard" is the same as checking "wizard" and "!quell".
*
* @param ref the object to check
* @param flag the flag (or alias) to check
*/
bool has_flag(dbref ref, const char *flag);

/**
* Find a dbref in an objnode list
*
Expand Down Expand Up @@ -2363,6 +2375,19 @@ void set_source(dbref action, dbref source);
*/
size_t size_object(dbref i, int load);

/**
* Returns the flag associated with the given string, if any.
*
* Understands flag alias prefixes.
*
* Passing "truewizard" here just returns the WIZARD flag.
*
* @param ref the object to check
* @param flag_string the flag (or alias) to check
* @return the flag corresponding to the string, or 0 if none match.
*/
object_flag_type str_to_flag(const char *flag_string);

/**
* "Unparses" flags, or rather, gives a string representation of object flags
*
Expand Down
19 changes: 19 additions & 0 deletions include/mfun.h
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,24 @@ const char *mfn_exits(MFUNARGS);
*/
const char *mfn_filter(MFUNARGS);

/**
* MPI function that returns if an object if it has the given flag (re)set.
*
* @see has_flag
*
* @param descr the descriptor of the caller
* @param player the ref of the calling player
* @param what the dbref of the trigger
* @param perms the dbref for permission consideration
* @param argc the number of arguments
* @param argv the array of strings for arguments
* @param buf the working buffer
* @param buflen the size of the buffer
* @param mesgtyp the type of the message
* @return string parsed results
*/
const char *mfn_flagp(MFUNARGS);

/**
* MPI function that returns the object flags for provided object as a string.
*
Expand Down Expand Up @@ -2985,6 +3003,7 @@ static struct mfun_dat mfun_list[] = {
{"EXEC!", mfn_execbang, 1, 0, 1, 1, 2},
{"EXITS", mfn_exits, 1, 0, 1, 1, 1},
{"FILTER", mfn_filter, 0, 0, 0, 3, 5},
{"FLAG?", mfn_flagp, 1, 0, 1, 2, 2},
{"FLAGS", mfn_flags, 1, 0, 1, 1, 1},
{"FOLD", mfn_fold, 0, 0, 0, 4, 5},
{"FOR", mfn_for, 0, 0, 0, 5, 5},
Expand Down
123 changes: 123 additions & 0 deletions src/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -2339,3 +2339,126 @@ env_distance(dbref from, dbref to)

return distance;
}

/**
* Returns the flag associated with the given string, if any.
*
* Understands flag alias prefixes.
*
* Passing "truewizard" here just returns the WIZARD flag.
*
* @param ref the object to check
* @param flag_string the flag (or alias) to check
* @return the flag corresponding to the string, or 0 if none match.
*/
object_flag_type
str_to_flag(const char *flag_string)
{
if (!*flag_string) {
return 0;
}

if (string_prefix("abode", flag_string)
|| string_prefix("autostart", flag_string)
|| string_prefix("abate", flag_string)) {
return ABODE;
} else if (string_prefix("builder", flag_string)
|| string_prefix("bound", flag_string)) {
return BUILDER;
} else if (string_prefix("chown_ok", flag_string)
|| string_prefix("color", flag_string)) {
return CHOWN_OK;
} else if (string_prefix("dark", flag_string)
|| string_prefix("debug", flag_string)) {
return DARK;
} else if (string_prefix("guest", flag_string)) {
return GUEST;
} else if (string_prefix("haven", flag_string)
|| string_prefix("hide", flag_string)
|| string_prefix("harduid", flag_string)) {
return HAVEN;
} else if (string_prefix("interactive", flag_string)) {
return INTERACTIVE;
} else if (string_prefix("jump_ok", flag_string)) {
return JUMP_OK;
} else if (string_prefix("kill_ok", flag_string)) {
return KILL_OK;
} else if (string_prefix("link_ok", flag_string)) {
return LINK_OK;
} else if (string_prefix("mucker", flag_string)) {
return MUCKER;
} else if (string_prefix("nucker", flag_string)) {
return SMUCKER;
} else if (string_prefix("overt", flag_string)) {
return (int)OVERT;
} else if (string_prefix("quell", flag_string)) {
return QUELL;
} else if (string_prefix("sticky", flag_string)
|| string_prefix("silent", flag_string)
|| string_prefix("setuid", flag_string)) {
return STICKY;
} else if (string_prefix("vehicle", flag_string)
|| string_prefix("viewable", flag_string)) {
return VEHICLE;
} else if (string_prefix("wizard", flag_string)) {
return WIZARD;
} else if (string_prefix("truewizard", flag_string)) {
return WIZARD;
} else if (string_prefix("xforcible", flag_string)
|| string_prefix("xpress", flag_string)) {
return XFORCIBLE;
} else if (string_prefix("yield", flag_string)) {
return YIELD;
} else if (string_prefix("zombie", flag_string)) {
return ZOMBIE;
}

return 0;
}


/**
* Returns true if the object has the given flag set (or reset).
*
* Understands flag alias prefixes and multiple not conditions (!!x = x).
*
* Checking "truewizard" is the same as checking "wizard" and "!quell".
*
* @param ref the object to check
* @param flag the flag (or alias) to check
* @return if the object has the specific flag state
*/
bool
has_flag(dbref ref, const char *flag)
{
object_flag_type tmp = 0;
int truwiz = 0;
bool result, negated = false;

while (*flag == NOT_TOKEN) {
flag++;
negated = (!negated);
}

if (string_prefix("truewizard", flag)) {
truwiz = 1;
}

tmp = str_to_flag(flag);

if (negated) {
if ((!truwiz) && (tmp == WIZARD)) {
result = (!Wizard(ref));
} else {
result = (tmp && ((FLAGS(ref) & tmp) == 0));
}
} else {
if ((!truwiz) && (tmp == WIZARD)) {
result = Wizard(ref);
} else {
result = (tmp && ((FLAGS(ref) & tmp) != 0));
}
}

return result;
}
34 changes: 34 additions & 0 deletions src/mfuns2.c
Original file line number Diff line number Diff line change
Expand Up @@ -3460,3 +3460,37 @@ mfn_width(MFUNARGS)

return buf;
}

/**
* MPI function that returns if an object if it has the given flag (re)set.
*
* @see has_flag
*
* @param descr the descriptor of the caller
* @param player the ref of the calling player
* @param what the dbref of the trigger
* @param perms the dbref for permission consideration
* @param argc the number of arguments
* @param argv the array of strings for arguments
* @param buf the working buffer
* @param buflen the size of the buffer
* @param mesgtyp the type of the message
* @return string parsed results
*/

const char *
mfn_flagp(MFUNARGS)
{
dbref obj = mesg_dbref_local(descr, player, what, perms, argv[0], mesgtyp);

if (obj == PERMDENIED || obj == AMBIGUOUS || obj == UNKNOWN || obj == NOTHING ||
obj == HOME) {
ABORT_MPI("FLAG?", "Failed match. (arg1)");
}

if (has_flag(obj, argv[1])) {
return "1";
} else {
return "0";
}
}
Loading

0 comments on commit 402d60d

Please sign in to comment.