/* $Header: set.c,v 2.0 90/05/05 12:45:42 lachesis Exp $ * $Log: set.c,v $ * Revision 2.0 90/05/05 12:45:42 lachesis * Incorporated ABODE and HAVEN flags (remembering to convert FireFoot's * usage of those flags to ours). * Added Examine of objects that don't belong to you, added GOD_PRIV. * * Revision 1.3 90/04/21 17:20:48 lachesis * Added property lists. * * Revision 1.2 90/04/20 14:06:51 lachesis * Added @odrop && @drop. * * Revision 1.1 90/04/14 14:56:51 lachesis * Initial revision * */ #include "copyright.h" /* commands which set parameters */ #include "os.h" #include "db.h" #include "config.h" #include "match.h" #include "interface.h" #include "externs.h" #ifdef COMPRESS #define alloc_compressed(x) alloc_string(compress(x)) #else /* COMPRESS */ #define alloc_compressed(x) alloc_string(x) #endif /* COMPRESS */ static dbref match_controlled (dbref player, const char *name) { dbref match; init_match (player, name, NOTYPE); match_everything (); match = noisy_match_result (); if (match != NOTHING && !controls (player, match)) { notify (player, "Permission denied."); return NOTHING; } else { return match; } } void do_name (dbref player, const char *name, char *newname) { dbref thing; char *password; if ((thing = match_controlled (player, name)) != NOTHING) { /* 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) { if (!db[thing].sp.player.password) { notify (player, "Sorry"); return; } /* split off password */ for (password = newname; *password && !isspace (*password); password++) /*EMPTY*/; /* 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"); return; } else if (strcmp (password, db[thing].sp.player.password)) { notify (player, "Incorrect password."); return; } else if (string_compare (newname, db[thing].name) && !ok_player_name (newname)) { notify (player, "You can't give a player that name."); return; } /* everything ok, notify */ fprintf (stderr, "NAME CHANGE: %s(#%d) to %s\n", db[thing].name, thing, newname); delete_player (player); if (db[thing].name) { free ((void *) db[thing].name); } db[thing].name = alloc_string (newname); add_player (player); notify (player, "Name set."); return; } else { if (!ok_name (newname)) { notify (player, "That is not a reasonable name."); return; } } /* everything ok, change the name */ if (db[thing].name) { free ((void *) db[thing].name); } db[thing].name = alloc_string (newname); notify (player, "Name set."); } } void do_describe (dbref player, const char *name, const char *description) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].description) { free ((void *) db[thing].description); } db[thing].description = alloc_compressed (description); notify (player, "Description set."); } } void do_fail (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].fail_message) { free ((void *) db[thing].fail_message); } db[thing].fail_message = alloc_compressed (message); notify (player, "Message set."); } } void do_success (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].succ_message) { free ((void *) db[thing].succ_message); } db[thing].succ_message = alloc_compressed (message); notify (player, "Message set."); } } /* sets the drop message for player */ void do_drop_message (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].drop_message) { free ((void *) db[thing].drop_message); } db[thing].drop_message = alloc_compressed (message); notify (player, "Message set."); } } void do_osuccess (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].osuccess) { free ((void *) db[thing].osuccess); } db[thing].osuccess = alloc_compressed (message); notify (player, "Message set."); } } void do_ofail (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].ofail) { free ((void *) db[thing].ofail); } db[thing].ofail = alloc_compressed (message); notify (player, "Message set."); } } void do_odrop (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].odrop) { free ((void *) db[thing].odrop); } db[thing].odrop = alloc_compressed (message); notify (player, "Message set."); } } void do_lock (dbref player, const char *name, const char *keyname) { dbref thing; struct boolexp *key; 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; } break; } key = parse_boolexp (player, keyname); if (key == TRUE_BOOLEXP) { notify (player, "I don't understand that key."); } else { /* everything ok, do it */ free_boolexp (db[thing].key); db[thing].key = key; notify (player, "Locked."); } } void do_unlock (dbref player, const char *name) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { free_boolexp (db[thing].key); db[thing].key = TRUE_BOOLEXP; notify (player, "Unlocked."); } } void do_unlink (dbref player, const char *name) { dbref exit; init_match (player, name, TYPE_EXIT); match_all_exits (); 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: db[exit].sp.exit.ndest = 0; if (db[exit].sp.exit.dest) free (db[exit].sp.exit.dest); db[exit].sp.exit.dest = 0; notify (player, "Unlinked."); break; case TYPE_ROOM: db[exit].sp.room.dropto = NOTHING; notify (player, "Dropto removed."); break; default: notify (player, "You can't unlink that!"); break; } } } } #ifdef PLAYER_CHOWN void do_chown (dbref player, const char *name, const char *newowner) { dbref thing; dbref owner; if (!*name) { notify (player, "You must specify what you want to take ownership of."); return; } #if 0 if (!Wizard (player) && *newowner) { notify (player, "Only wizards can transfer ownership to others."); return; } #endif init_match (player, name, NOTYPE); match_everything (); if ((thing = noisy_match_result ()) == NOTHING) return; if (*newowner && string_compare (newowner, "me")) { if ((owner = lookup_player (newowner)) == NOTHING) { notify (player, "I couldn't find that player."); return; } } else { owner = player; } if (!Wizard (player) && (!(db[thing].flags & CHOWN_OK) || !could_doit (player, thing))) { notify (player, "You can't take possession of that."); return; } switch (Typeof (thing)) { case TYPE_ROOM: if (!Wizard (player) && (db[player].location != thing)) { notify (player, "You cannot chown another room."); return; } db[thing].sp.room.owner = owner; break; case TYPE_THING: db[thing].sp.thing.owner = owner; break; case TYPE_EXIT: db[thing].sp.exit.owner = owner; break; case TYPE_PLAYER: notify (player, "Players always own themselves."); return; #ifdef RECYCLE case TYPE_GARBAGE: notify (player, "No one wants to own garbage."); return; #endif } if (owner == player) notify (player, "Owner changed to you."); else notify (player, "Owner changed."); } #else /* without PLAYER_CHOWN */ void do_chown (dbref player, const char *name, const char *newowner) { dbref thing; dbref owner; if (!Wizard (player)) { notify (player, "Permission denied."); return; } init_match (player, name, NOTYPE); match_everything (); if ((thing = noisy_match_result ()) == NOTHING) return; if ((owner = lookup_player (newowner)) == NOTHING) { notify (player, "I couldn't find that player."); return; } switch (Typeof (thing)) { case TYPE_ROOM: db[thing].sp.room.owner = owner; break; case TYPE_THING: db[thing].sp.thing.owner = owner; break; case TYPE_EXIT: db[thing].sp.exit.owner = owner; break; case TYPE_PLAYER: notify (player, "Players always own themselves."); return; #ifdef RECYCLE case TYPE_GARBAGE: notify (player, "No one wants to own garbage."); return; #endif } notify (player, "Owner changed."); } #endif /* PLAYER_CHOWN */ /* Note: Gender code taken out. All gender references are now to be handled by property lists... Setting of flags and property code done here. Note that the PROP_DELIMITER identifies when you're setting a property. A @set <thing>= : will clear all properties. A @set <thing>= type: will remove that property. A @set <thing>= type: class will add that property or replace it. */ void do_set (dbref player, const char *name, const char *flag) { dbref thing; const char *p; object_flag_type f; /* find thing */ if ((thing = match_controlled (player, name)) == NOTHING) return; /* move p past NOT_TOKEN if present */ for (p = flag; *p && (*p == NOT_TOKEN || isspace (*p)); p++) /*EMPTY*/; /* Now we check to see if it's a property reference */ /* if this gets changed, please also modify boolexp.c */ if (index (flag, PROP_DELIMITER)) { /* copy the string so we can muck with it */ char *type = get_string (flag); /* type */ char *class = index (type, PROP_DELIMITER); /* class */ char *x = type; /* to preserve string location so we can free it */ char *temp; struct plist *prop, *last; while (isspace (*type) && (*type != PROP_DELIMITER)) type++; if (*type == PROP_DELIMITER) { /* clear all properties */ for (last = prop = db[thing].properties; prop; prop = last) { last = prop->next; free_prop (prop); } notify (player, "All properties removed."); free ((void *) x); db[thing].properties = 0; return; } else { /* get rid of trailing spaces */ for (temp = class - 1; isspace (*temp); temp--) /*EMPTY*/; temp++; *temp = '\0'; } class++; /* move to next character */ while (isspace (*class) && *class) class++; if (!(*class)) { remove_property (thing, type); notify (player, "Property removed."); } else { /* remove trailing spaces */ for (temp = class + strlen (class); isspace (*temp) && temp > class; temp--) /*EMPTY*/; *temp = '\0'; add_property (thing, type, class, 0); notify (player, "Property set."); } free ((void *) x); return; } /* identify flag */ if (*p == '\0') { notify (player, "You must specify a flag to set."); return; } else if (string_prefix ("LINK_OK", p)) { f = LINK_OK; } else if (string_prefix ("DARK", p)) { f = DARK; } else if (string_prefix ("STICKY", p)) { f = STICKY; } else if (string_prefix ("WIZARD", p)) { f = WIZARD; } else if (string_prefix ("TEMPLE", p)) { f = TEMPLE; #ifdef RESTRICTED_BUILDING } else if (string_prefix ("BUILDER", p)) { f = BUILDER; #endif /* RESTRICTED_BUILDING */ #ifdef PLAYER_CHOWN } else if (string_prefix ("CHOWN_OK", p)) { f = CHOWN_OK; #endif /* PLAYER_CHOWN */ } else if (string_prefix ("JUMP_OK", p)) { f = JUMP_OK; #ifdef HAVEN } else if (string_prefix ("HAVEN", p)) { f = HAVEN; #endif /* HAVEN */ #ifdef ABODE } else if (string_prefix ("ABODE", p)) { f = ABODE; #endif /* ABODE */ } else { notify (player, "I don't recognize that flag."); return; } /* check for restricted flag */ if (!Wizard (player) && (f == WIZARD #ifdef RESTRICTED_BUILDING || f == BUILDER #endif /* RESTRICTED_BUILDING */ || f == TEMPLE || f == DARK && Typeof (thing) != TYPE_ROOM)) { notify (player, "Permission denied."); return; } /* check for stupid wizard */ if (f == WIZARD && *flag == NOT_TOKEN && thing == player) { notify (player, "You cannot make yourself mortal."); return; } #ifdef GOD_PRIV if (f == WIZARD && *flag == NOT_TOKEN && God (thing)) { notify (player, "Even wizards can't make God mortal."); return; } #endif /* GOD_PRIV */ /* else everything is ok, do the set */ if (*flag == NOT_TOKEN) { /* reset the flag */ db[thing].flags &= ~f; notify (player, "Flag reset."); } else { /* set the flag */ db[thing].flags |= f; notify (player, "Flag set."); } }