/* $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 <stdio.h> #include <ctype.h> #include <string.h> /* in some systems you may have to change this to strings.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."); } }