/* set.c */
#include "copyright.h"
/* commands which set parameters */
#ifdef WANT_ANSI
#ifdef __STDC__
#include <stddef.h>
#include <stdlib.h>
#endif /* __STDC__ */
#endif /* WANT_ANSI */
#include <stdio.h>
#include <ctype.h>
#include "mudconf.h"
#include "config.h"
#include "db.h"
#include "match.h"
#include "interface.h"
#include "externs.h"
#include "flags.h"
extern NAMETAB indiv_attraccess_nametab[];
dbref match_controlled(dbref player, const char *name)
{
dbref mat;
init_match(player, name, NOTYPE);
match_everything();
mat = noisy_match_result();
if (mat != NOTHING && !Controls(player, mat)) {
notify(player, "Permission denied.");
return NOTHING;
} else {
return (mat);
}
}
dbref match_affected(dbref player, const char *name)
{
dbref mat;
init_match(player, name, NOTYPE);
match_everything();
mat = noisy_match_result();
if (mat != NOTHING && !Affects(player, mat)) {
notify(player, "Permission denied.");
return NOTHING;
} else {
return (mat);
}
}
dbref match_examinable(dbref player, const char *name)
{
dbref mat;
init_match(player, name, NOTYPE);
match_everything();
mat = noisy_match_result();
if (mat != NOTHING && !Examinable(player, mat)) {
notify(player, "Permission denied.");
return NOTHING;
} else {
return (mat);
}
}
void do_name(dbref player, dbref cause, int key, char *name, char *newname)
{
dbref thing;
char *password, *buff;
if ((thing = match_controlled(player, name)) == NOTHING)
return;
/* check for bad name */
if (*newname == '\0') {
notify(player, "Give it what new name?");
return;
}
/* check for renaming a player */
if (Typeof(thing) == TYPE_PLAYER) {
buff = trim_spaces(newname);
/* split off password */
for (password = buff;
*password && !isspace(*password);
password++) ;
/* eat whitespace */
if (*password) {
*password++ = '\0'; /* terminate name */
while (*password && isspace(*password))
password++;
}
/* check for null password */
if (!*password) {
notify(player,
"You must specify a password to change a player name.");
notify(player, "E.g.: name player = newname password");
free_lbuf(buff);
return;
} else if (!check_pass(thing, password)) {
notify(player, "Incorrect password.");
free_lbuf(buff);
return;
} else if (!ok_player_name(buff) ||
!badname_check(buff)) {
notify(player, "You can't use that name.");
free_lbuf(buff);
return;
} else if (string_compare(buff, Name(thing)) &&
(lookup_player(NOTHING, buff, 0) != NOTHING)) {
/* string_compare allows changing foo to Foo, etc. */
notify(player, "That name is already in use.");
free_lbuf(buff);
return;
}
/* everything ok, notify */
STARTLOG(LOG_SECURITY,"SEC","CNAME")
log_name(thing),
log_text((char *)" renamed to ");
log_text(buff);
ENDLOG
if (Suspect(thing)) {
raw_broadcast(WIZARD,"[Suspect] %s renamed to %s",
Name(thing), buff);
}
delete_player_name(thing, Name(thing));
s_Name(thing, buff);
add_player_name(thing, Name(thing));
if (!Quiet(player) && !Quiet(thing))
notify(player, "Name set.");
free_lbuf(buff);
return;
} else {
if (!ok_name(newname)) {
notify(player, "That is not a reasonable name.");
return;
}
/* everything ok, change the name */
s_Name(thing, newname);
if (!Quiet(player) && !Quiet(thing))
notify(player, "Name set.");
}
}
/* ---------------------------------------------------------------------------
* do_alias: Make an alias for a player or object.
*/
void do_alias (dbref player, dbref cause, int key, char *name, char *alias)
{
dbref thing, aowner;
int aflags;
ATTR *ap;
char *oldalias, *trimalias;
if ((thing = match_controlled(player, name)) == NOTHING)
return;
/* check for renaming a player */
ap = atr_num(A_ALIAS);
if (Typeof(thing) == TYPE_PLAYER) {
/* Fetch the old alias */
oldalias = atr_pget(thing, A_ALIAS, &aowner, &aflags);
trimalias = trim_spaces(alias);
if (!Controls(player, thing)) {
/* Make sure we have rights to do it. We can't do
* the normal Set_attr check because ALIAS is only
* writable by GOD and we want to keep people from
* doing &ALIAS and bypassing the player name checks.
*/
notify(player, "Permission denied.");
} else if (!*trimalias) {
/* New alias is null, just clear it */
delete_player_name(thing, oldalias);
if (!Quiet(player))
notify(player, "Alias removed.");
} else if (lookup_player(NOTHING, trimalias, 0) != NOTHING) {
/* Make sure new alias isn't already in use */
notify(player, "That name is already in use.");
} else {
/* Remove the old name and add the new name */
delete_player_name(thing, oldalias);
atr_add(thing, A_ALIAS, trimalias, Owner(player),
aflags);
if (add_player_name(thing, trimalias)) {
if (!Quiet(player))
notify(player, "Alias set.");
} else {
notify(player, "Error setting alias.");
}
free_lbuf(trimalias);
}
free_lbuf(oldalias);
} else {
atr_pget_info(thing, A_ALIAS, &aowner, &aflags);
/* Make sure we have rights to do it */
if (!Set_attr(player, thing, ap, aflags)) {
notify(player, "Permission denied.");
} else {
atr_add(thing, A_ALIAS, alias, Owner(player), aflags);
if (!Quiet(player))
notify(player, "Set.");
}
}
}
/* ---------------------------------------------------------------------------
* do_lock: Set a lock on an object or attribute.
*/
void do_lock(dbref player, dbref cause, int key, char *name, char *keytext)
{
dbref thing, aowner;
int atr, aflags;
ATTR *ap;
struct boolexp *okey;
if (parse_attrib(player, name, &thing, &atr)) {
if (atr != NOTHING) {
if (!atr_get_info(thing, atr, &aowner, &aflags)) {
notify(player,
"Attribute not present on object.");
return;
}
ap = atr_num(atr);
/* You may lock an attribute if:
* you could write the attribute if it were stored on
* yourself
* --and--
* you own the attribute or are a wizard as long as
* you are not #1 and are trying to do something to #1.
*/
if (ap && (God(player) ||
(!God(thing) && Set_attr(player, player, ap, 0) &&
(Wizard(player) ||
(aowner == Owner(player)))))) {
aflags |= AF_LOCK;
atr_set_flags(thing, atr, aflags);
if (!Quiet(player) && !Quiet(thing))
notify(player, "Attribute locked.");
} else {
notify(player, "Permission denied.");
}
return;
}
}
init_match(player, name, NOTYPE);
match_everything();
switch (thing = match_result()) {
case NOTHING:
notify(player, "I don't see what you want to lock!");
return;
case AMBIGUOUS:
notify(player, "I don't know which one you want to lock!");
return;
default:
if (!controls(player, thing)) {
notify(player, "You can't lock that!");
return;
}
}
okey = parse_boolexp(player, keytext);
if (okey == TRUE_BOOLEXP) {
notify(player, "I don't understand that key.");
} else {
/* everything ok, do it */
if (!key)
key = A_LOCK;
atr_add_raw(thing, key, unparse_boolexp_quiet(player, okey));
if (!Quiet(player) && !Quiet(thing))
notify(player, "Locked.");
}
free_boolexp(okey);
}
/* ---------------------------------------------------------------------------
* Remove a lock from an object of attribute.
*/
void do_unlock(dbref player, dbref cause, int key, char *name)
{
dbref thing, aowner;
int atr, aflags;
ATTR *ap;
if (parse_attrib(player, name, &thing, &atr)) {
if (atr != NOTHING) {
if (!atr_get_info(thing, atr, &aowner, &aflags)) {
notify(player,
"Attribute not present on object.");
return;
}
ap = atr_num(atr);
/* You may unlock an attribute if:
* you could write the attribute if it were stored on
* yourself
* --and--
* you own the attribute or are a wizard as long as
* you are not #1 and are trying to do something to #1.
*/
if (ap && (God(player) ||
(!God(thing) && Set_attr(player, player, ap, 0) &&
(Wizard(player) ||
(aowner == Owner(player)))))) {
aflags &= ~AF_LOCK;
atr_set_flags(thing, atr, aflags);
if (Owner(player != Owner(thing)))
if (!Quiet(player) && !Quiet(thing))
notify(player, "Attribute unlocked.");
} else {
notify(player, "Permission denied.");
}
return;
}
}
if (!key)
key = A_LOCK;
if ((thing = match_controlled(player, name)) != NOTHING) {
atr_clr(thing, key);
if (!Quiet(player) && !Quiet(thing))
notify(player, "Unlocked.");
}
}
/* ---------------------------------------------------------------------------
* do_unlink: Unlink an exit from its destination or remove a dropto.
*/
void do_unlink(dbref player, dbref cause, int key, char *name)
{
dbref exit;
init_match(player, name, TYPE_EXIT);
match_exit();
match_here();
if (Wizard(player)) {
match_absolute();
}
switch (exit = match_result()) {
case NOTHING:
notify(player, "Unlink what?");
break;
case AMBIGUOUS:
notify(player, "I don't know which one you mean!");
break;
default:
if (!controls(player, exit)) {
notify(player, "Permission denied.");
} else {
switch (Typeof(exit)) {
case TYPE_EXIT:
s_Location(exit, NOTHING);
if (!Quiet(player))
notify(player, "Unlinked.");
break;
case TYPE_ROOM:
s_Dropto(exit, NOTHING);
if (!Quiet(player))
notify(player, "Dropto removed.");
break;
default:
notify(player, "You can't unlink that!");
break;
}
}
}
}
/* ---------------------------------------------------------------------------
* do_chown: Change ownership of an object or attribute.
*/
void do_chown(dbref player, dbref cause, int key, char *name, char *newown)
{
dbref thing, owner, aowner;
int atr, aflags, do_it, cost, quota;
ATTR *ap;
if (parse_attrib(player, name, &thing, &atr)) {
if (atr != NOTHING) {
if (!*newown) {
owner = Owner(thing);
} else if (!(string_compare(newown, "me"))) {
owner = Owner(player);
} else {
owner = lookup_player(player, newown, 1);
}
/* You may chown an attr to yourself if you own the
* object and the attr is not locked.
* You may chown an attr to the owner of the object if
* you own the attribute.
* To do anything else you must be a wizard.
* Only #1 can chown attributes on #1.
*/
if (!atr_get_info(thing, atr, &aowner, &aflags)) {
notify(player,
"Attribute not present on object.");
return;
}
do_it = 0;
if (owner == NOTHING) {
notify(player, "I couldn't find that player.");
} else if (God(thing) && !God(player)) {
notify(player, "Permission denied.");
} else if (Wizard(player)) {
do_it = 1;
} else if (owner == Owner(player)) {
/* chown to me: only if I own the obj and
* !locked */
if (!Controls(player, thing) ||
(aflags & AF_LOCK)) {
notify(player, "Permission denied.");
} else {
do_it = 1;
}
} else if (owner == Owner(thing)) {
/* chown to obj owner: only if I own attr
* and !locked */
if ((Owner(player) != aowner) ||
(aflags & AF_LOCK)) {
notify(player, "Permission denied.");
} else {
do_it = 1;
}
} else {
notify(player, "Permission denied.");
}
if (!do_it) return;
ap = atr_num(atr);
if (!ap || !Set_attr(player, player, ap, aflags)) {
notify(player, "Permission denied.");
return;
}
atr_set_owner(thing, atr, owner);
if (!Quiet(player))
notify(player, "Attribute owner changed.");
return;
}
}
init_match(player, name, TYPE_THING);
match_possession();
match_here();
match_exit();
match_me();
if(Wizard(player)) {
match_player();
match_absolute();
}
switch (thing = match_result()) {
case NOTHING:
notify(player, "You don't have that!");
return;
case AMBIGUOUS:
notify(player, "I don't know which you mean!");
return;
}
if (!*newown || !(string_compare(newown, "me"))) {
owner = Owner(player);
} else {
owner = lookup_player(player, newown, 1);
}
cost = 1;
quota = 1;
switch (Typeof(thing)) {
case TYPE_ROOM:
cost = mudconf.digcost;
quota = mudconf.room_quota;
break;
case TYPE_THING:
cost = OBJECT_DEPOSIT(Pennies(thing));
quota = mudconf.thing_quota;
break;
case TYPE_EXIT:
cost = mudconf.opencost;
quota = mudconf.exit_quota;
break;
case TYPE_PLAYER:
cost = mudconf.robotcost;
quota = mudconf.player_quota;
}
if (owner == NOTHING) {
notify(player, "I couldn't find that player.");
} else if (Typeof(thing) == TYPE_PLAYER && !God(player)) {
notify(player, "Players always own themselves.");
} else if ((!controls(player, thing) && (!(Flags(thing) & CHOWN_OK) ||
((Typeof(thing) == TYPE_THING) &&
(Location(thing) != player)))) ||
(!controls(player, owner))) {
notify(player, "Permission denied.");
} else if (canpayfees(player, owner, cost, quota)) {
giveto(Owner(thing), cost);
if (mudconf.quotas)
add_quota(Owner(thing), quota);
if(God(player)) {
s_Owner(thing, owner);
} else {
s_Owner(thing, Owner(owner));
}
atr_chown(thing);
s_Flags(thing, (Flags(thing) & ~(CHOWN_OK|INHERIT)) | HALT);
halt_que(NOTHING, thing);
if (!Quiet(player))
notify(player, "Owner changed.");
}
}
/* ---------------------------------------------------------------------------
* do_set: Set flags or attributes on objects, or flags on attributes.
*/
static void set_attr_internal (dbref player, dbref thing, int attrnum,
char *attrtext)
{
dbref aowner;
int aflags, could_hear;
ATTR *attr;
attr = atr_num(attrnum);
atr_pget_info(thing, attrnum, &aowner, &aflags);
if (Set_attr(player, thing, attr, aflags)) {
if ((attr->check != NULL) &&
(!(*attr->check)(0, player, thing, attrnum, attrtext)))
return;
could_hear = Hearer(thing);
atr_add(thing, attrnum, attrtext, Owner(player), aflags);
handle_ears(thing, could_hear, Hearer(thing));
if (!Quiet(player) && !Quiet(thing))
notify(player, "Set.");
} else {
notify(player, "Permission denied.");
}
}
void do_set(dbref player, dbref cause, int key, char *name, char *flag)
{
dbref thing, aowner;
char *p, *buff;
int canhear, atr, aflags, clear, flagvalue, could_hear;
ATTR *attr, *attr2;
/* See if we have the <obj>/<attr> form, which is how you set attribute
* flags.
*/
if (parse_attrib (player, name, &thing, &atr)) {
if (atr != NOTHING) {
/* You must specify a flag name */
if (!flag || !*flag) {
notify(player,
"I don't know what you want to set!");
return;
}
/* Check for clearing */
clear = 0;
if (*flag == NOT_TOKEN) {
flag++;
clear = 1;
}
/* Make sure player specified a valid attribute flag */
flagvalue = search_nametab (player,
indiv_attraccess_nametab, flag);
if (flagvalue == -1) {
notify(player, "You can't set that!");
return;
}
/* Make sure the object has the attribute present */
if (!atr_get_info(thing, atr, &aowner, &aflags)) {
notify(player,
"Attribute not present on object.");
return;
}
/* Make sure we can write to the attribute */
attr = atr_num(atr);
if (!Set_attr(player, thing, attr, aflags)) {
notify(player, "Permission denied.");
return;
}
/* Go do it */
if (clear)
aflags &= ~flagvalue;
else
aflags |= flagvalue;
could_hear = Hearer(thing);
atr_set_flags(thing, atr, aflags);
/* Tell the player about it. */
handle_ears(thing, could_hear, Hearer(thing));
if (!Quiet(player) && !Quiet(thing)) {
if (clear)
notify(player, "Cleared.");
else
notify(player, "Set.");
}
return;
}
}
/* find thing */
if ((thing = match_controlled(player, name)) == NOTHING)
return;
canhear = Hearer(thing);
/* check for attribute set first */
for (p = flag; *p && (*p != ':'); p++) ;
if (*p) {
*p++ = 0;
atr = mkattr(flag);
if (atr <= 0) {
notify(player, "Couldn't create attribute.");
return;
}
attr = atr_num(atr);
if (!attr) {
notify(player, "Permission denied.");
return;
}
atr_get_info(thing, atr, &aowner, &aflags);
if (!Set_attr(player, thing, attr, aflags)) {
notify(player, "Permission denied.");
return;
}
buff=alloc_lbuf("do_set");
/* check for _ */
if (*p == '_') {
strcpy(buff, p + 1);
if (!parse_attrib(player, p + 1, &thing, &atr) ||
(atr == NOTHING)) {
notify(player, "No match.");
free_lbuf(buff);
return;
}
attr2 = atr_num(atr);
p = buff;
atr_pget_str(buff, thing, atr, &aowner, &aflags);
if (!See_attr(player, thing, attr2, aowner)) {
notify(player, "Permission denied.");
free_lbuf(buff);
return;
}
}
/* Go set it */
set_attr_internal (player, thing, attr->number, p);
free_lbuf(buff);
return;
}
/* Set or clear a flag */
flag_set(thing, player, flag);
}
void do_setattr(dbref player, dbref cause, int attrnum, char *name,
char *attrtext)
{
dbref thing;
init_match(player, name, NOTYPE);
match_everything();
thing = noisy_match_result();
if (thing == NOTHING)
return;
set_attr_internal(player, thing, attrnum, attrtext);
}
void do_mvattr (dbref player, dbref cause, int key, char *what,
char *args[], int nargs)
{
dbref thing, aowner, axowner;
ATTR *in_attr, *out_attr;
int i, anum, isnum, aflags, axflags, no_delete;
char *astr;
/* Make sure we have something to do. */
if (nargs < 2) {
notify(player, "Nothing to do.");
return;
}
/* FInd and make sure we control the target object. */
thing = match_controlled(player, what);
if (thing == NOTHING)
return;
/* Look up the attribute. If the name check fails, try by number */
in_attr = atr_str(args[0]);
if (in_attr == NULL)
in_attr = atr_num(atoi(args[0]));
if (in_attr == NULL) {
notify(player, tprintf("%s: No such attribute.", args[0]));
return;
}
astr = atr_get(thing, in_attr->number, &aowner, &aflags);
if (!See_attr(player, thing, in_attr, aowner)) {
notify(player, tprintf("%s: Permission denied.", args[0]));
free_lbuf(astr);
return;
}
/* Copy the attribute to each target in turn. */
no_delete = 0;
for (i=1; i<nargs; i++) {
out_attr = atr_str(args[i]);
isnum = 0;
anum = 0;
if (out_attr == NULL) {
isnum = is_number(args[i]);
if (isnum) {
anum = atoi(args[i]);
} else {
anum = mkattr(args[i]);
}
if (anum > 0)
out_attr = atr_num(anum);
}
if (out_attr == NULL) {
if (!God(player) || !isnum) {
notify(player,
tprintf("%s is not a good name for an attribute.",
args[i]));
} else {
notify(player,
tprintf("Warning: Attribute # %d is not defined.",
anum));
atr_add(thing, anum, astr, Owner(player),
aflags);
}
continue;
}
if (out_attr->number == in_attr->number) {
no_delete = 1;
} else {
atr_get_info(thing, out_attr->number, &axowner,
&axflags);
if (!Set_attr(player, thing, out_attr, axflags)) {
notify(player,
tprintf("%s: Permission denied.",
args[i]));
} else {
atr_add(thing, out_attr->number, astr,
Owner(player), aflags);
if (!Quiet(player))
notify(player,
tprintf("Set: %s",
out_attr->name));
}
}
}
/* Remove the source attribute if we can. */
if (!no_delete) {
if (Set_attr(player, thing, in_attr, aflags)) {
atr_clr(thing, in_attr->number);
} else {
notify(player,
"Could not remove old attribute. Permission denied.");
}
}
free_lbuf(astr);
}
/* ---------------------------------------------------------------------------
* parse_attrib, parse_attrib_wild: parse <obj>/<attr> tokens.
*/
int parse_attrib(dbref player, char *str, dbref *thing, int *atr)
{
ATTR *attr;
char *buff;
dbref aowner;
int aflags;
if (!str)
return 0;
buff=alloc_lbuf("parse_attrib");
strcpy(buff, str);
/* get name up to / */
for (str=buff; *str && (*str!='/'); str++) ;
if (!*str) {
free_lbuf(buff);
return 0;
}
*str++ = 0;
init_match(player, buff, NOTYPE);
match_everything();
*thing = match_result();
if ((*thing == NOTHING) || (*thing == AMBIGUOUS)) {
free_lbuf(buff);
return 0;
}
/* rest is attrib name. Note: return true with atr=NOTHING if
* the attribute doesn't exist or is unreadable */
attr = atr_str(str);
free_lbuf(buff);
if (!attr) {
*atr = NOTHING;
} else {
atr_pget_info(*thing, attr->number, &aowner, &aflags);
if (!See_attr(player, *thing, attr, aowner)) {
*atr = NOTHING;
} else {
*atr = attr->number;
}
}
return 1;
}
int parse_attrib_wild(dbref player, char *str, dbref *thing, int get_locks)
{
ATTR *attr;
char *buff, *as;
dbref aowner;
int aflags, ca, ok;
olist_init();
if (!str)
return 0;
buff=alloc_lbuf("parse_attrib_wild");
strcpy(buff, str);
/* get name up to / */
for (str=buff; *str && (*str!='/'); str++) ;
if (!*str) {
free_lbuf(buff);
return 0;
}
*str++ = '\0';
init_match(player, buff, NOTYPE);
match_everything();
*thing = match_result();
if ((*thing == NOTHING) || (*thing == AMBIGUOUS)) {
free_lbuf(buff);
return 0;
}
/* Process the object's attribute list, storing matches in the olist
* area.
*/
for (ca=atr_head(*thing, &as); ca; ca=atr_next(&as)) {
attr = atr_num(ca);
if (attr) {
atr_get_info(*thing, ca, &aowner, &aflags);
if (get_locks)
ok = Read_attr(player, *thing, attr, aowner);
else
ok = See_attr(player, *thing, attr, aowner);
if (ok && quick_wild(str, (char *)attr->name)) {
olist_add(ca);
}
}
}
free_lbuf(buff);
return 1;
}
/* ---------------------------------------------------------------------------
* edit_string, do_edit: Modify attributes.
*/
void edit_string (char *src, char **dst, char *from, char *to)
{
char *cp;
/* Do the substitution. Idea for prefix/suffix from R'nice@TinyTIM */
if (!strcmp(from, "^")) {
/* Prepend 'to' to string */
*dst = alloc_lbuf("edit_string.^");
cp = *dst;
safe_str(to, *dst, &cp);
safe_str(src, *dst, &cp);
*cp = '\0';
} else if (!strcmp(from, "$")) {
/* Append 'to' to string */
*dst = alloc_lbuf("edit_string.$");
cp = *dst;
safe_str(src, *dst, &cp);
safe_str(to, *dst, &cp);
*cp = '\0';
} else {
/* replace all occurances of from with to */
*dst = replace_string(from, to, src);
}
}
void do_edit(dbref player, dbref cause, int key, char *it,
char *args[], int nargs)
{
dbref thing, aowner;
int attr, got_one, aflags, doit;
char *from, *to, *result, *atext;
ATTR *ap;
/* Make sure we have something to do. */
if ((nargs < 1) || !*args[0]) {
notify(player, "Nothing to do.");
return;
}
from = args[0];
to = (nargs >= 2) ? args[1] : (char *)"";
/* Look for the object and get the attribute (possibly wildcarded) */
if (!it || !*it || !parse_attrib_wild(player, it, &thing, 0)) {
notify(player, "No match.");
return;
}
/* Iterate through matching attributes, performing edit */
got_one = 0;
atext = alloc_lbuf("do_edit.atext");
for (attr=olist_first(); attr!=NOTHING; attr=olist_next()) {
ap = atr_num(attr);
if (ap) {
/* Get the attr and make sure we can modify it. */
atr_get_str(atext, thing, ap->number,
&aowner, &aflags);
if (Set_attr(player, thing, ap, aflags)) {
/* Do the edit and save the result */
got_one = 1;
edit_string(atext, &result, from, to);
if (ap->check != NULL) {
doit = (*ap->check)(0, player, thing,
ap->number, result);
} else {
doit = 1;
}
if (doit) {
atr_add(thing, ap->number, result,
Owner(player), aflags);
if (!Quiet(player))
notify(player,
tprintf("Set - %s: %s",
ap->name,
result));
}
free_lbuf(result);
} else {
/* No rights to change the attr */
notify(player,
tprintf("%s: Permission denied.",
ap->name));
}
}
}
/* Clean up */
free_lbuf(atext);
olist_init();
if (!got_one) {
notify(player, "No matching attributes.");
}
}
void do_trigger(dbref player, dbref cause, int key, char *object,
char *argv[], int nargs)
{
dbref thing;
int attrib;
if (!parse_attrib(player, object, &thing, &attrib) || (attrib == NOTHING)) {
notify(player, "No match.");
return;
}
if (!controls(player, thing)) {
notify(player, "Permission denied.");
return;
}
did_it(player, thing, 0, NULL, 0, NULL, attrib, argv, nargs);
if (!Quiet(player)) notify(player, "Triggered.");
/* XXX be more descriptive as to what was triggered? */
}
void do_use (dbref player, dbref cause, int key, char *object)
{
char *df_use, *df_ouse, *temp;
dbref thing, aowner;
int aflags, doit;
init_match(player, object, NOTYPE);
match_neighbor();
match_possession();
if (Wizard(player)) {
match_absolute();
match_player();
}
match_me();
match_here();
thing = noisy_match_result();
if (thing == NOTHING) return;
/* Make sure player can use it */
if (!could_doit(player, thing, A_LUSE)) {
did_it(player, thing, A_UFAIL,
"You can't figure out how to use that.",
A_OUFAIL, NULL, A_AUFAIL, (char **)NULL, 0);
return;
}
temp = alloc_lbuf("do_use");
doit = 0;
if (*atr_pget_str(temp, thing, A_USE, &aowner, &aflags))
doit = 1;
else if (*atr_pget_str(temp, thing, A_OUSE, &aowner, &aflags))
doit = 1;
else if (*atr_pget_str(temp, thing, A_AUSE, &aowner, &aflags))
doit = 1;
free_lbuf(temp);
if (doit) {
df_use = alloc_lbuf("do_use.use");
df_ouse = alloc_lbuf("do_use.ouse");
sprintf(df_use, "You use %s", Name(thing));
sprintf(df_ouse, "uses %s", Name(thing));
did_it (player, thing, A_USE, df_use, A_OUSE, df_ouse, A_AUSE,
(char **)NULL, 0);
free_lbuf(df_use);
free_lbuf(df_ouse);
} else {
notify(player, "You can't figure out how to use that.");
}
}
/* ---------------------------------------------------------------------------
* do_setvattr: Set a user-named (or possibly a predefined) attribute.
*/
void do_setvattr(dbref player, dbref cause, int key, char *arg1,
char *arg2)
{
char *s;
int anum;
arg1++; /* skip the '&' */
for (s=arg1; *s&&!isspace(*s); s++) ; /* take to the space */
if (*s) *s++='\0'; /* split it */
anum = mkattr(arg1); /* Get or make attribute */
if (anum <= 0) {
notify(player, "That's not a good name for an attribute.");
return;
}
do_setattr(player, cause, anum, s, arg2);
}