/* buildcmds.c */ #include "copyright.h" #include "config.h" #include <stdio.h> #ifdef STRING_H #include <string.h> #else #include <strings.h> #endif /* STRING_H */ #include <ctype.h> #include "teeny.h" /* * Building/Creating commands */ /* Buffer from cmds.c */ extern char cmdwork[]; voidfunc do_create(player, argone) int player; char *argone; { int obj, next, count, home, here; char *p; #ifdef RESTRICT_BUILDING if (!isbuilder(player) && !iswiz(player)) { notify_player(player, "That command is for authorized builders only.\r\n"); return; } #endif /* RESTRICT_BUILDING */ if (!argone || !*argone) { notify_player(player, "You need to specify a name.\r\n"); return; } if (!ok_name(argone)) { notify_player(player, "That's a silly name for an object!\r\n"); return; } /* Go to it */ obj = create_obj(TYP_THING); if (set_str_elt(obj, NAME, argone) == -1) goto createbomb; if (set_int_elt(obj, OWNER, player) == -1) goto createbomb; if (set_int_elt(obj, LOC, player) == -1) goto createbomb; if (get_int_elt(player, LOC, &here) == -1) goto createbomb; if (controls(player, here) || isabode(here)) { home = here; } else { if (get_int_elt(player, HOME, &home) == -1) goto createbomb; } if (set_int_elt(obj, HOME, home) == -1) goto createbomb; if (get_int_elt(player, CONTENTS, &next) == -1) goto createbomb; if (set_int_elt(player, CONTENTS, obj) == -1) goto createbomb; if (set_int_elt(obj, NEXT, next) == -1) goto createbomb; #ifdef TIMESTAMPS stamp(obj); #endif /* TIMESTAMPS */ /* Tell the player */ p = cmdwork; count = 0; strcpy(p, "Object "); p += 7; count += 7; while (*argone && count < BUFFSIZ - 33) { *p++ = *argone++; count++; } strcpy(p, " created with number #"); p += 22; p = ty_itoa(p, obj); *p++ = '.'; *p++ = '\r'; *p++ = '\n'; *p = '\0'; notify_player(player, cmdwork); return; createbomb: notify_bad(player); return; } voidfunc do_dig(player, arg) int player; char *arg; { int room, count; char *p; #ifdef RESTRICT_BUILDING if (!isbuilder(player) && !iswiz(player)) { notify_player(player, "That command is for authorized builders only.\r\n"); return; } #endif /* RESTRICT_BUILDING */ if (!arg || !*arg) { notify_player(player, "You need to specify a name.\r\n"); return; } if (!ok_name(arg)) { notify_player(player, "That's a silly name for a room!\r\n"); return; } room = create_obj(TYP_ROOM); if (set_int_elt(room, OWNER, player) == -1) goto digbomb; if (set_str_elt(room, NAME, arg) == -1) goto digbomb; #ifdef TIMESTAMPS stamp(room); #endif /* TIMESTAMPS */ /* Tell the player */ p = cmdwork; count = 0; strcpy(p, "Room "); p += 5; count += 5; while (*arg && count < BUFFSIZ - 33) { *p++ = *arg++; count++; } strcpy(p, " dug with number #"); p += 18; p = ty_itoa(p, room); *p++ = '.'; *p++ = '\r'; *p++ = '\n'; *p = '\0'; notify_player(player, cmdwork); return; digbomb: notify_bad(player); return; } void do_set_string(player, argone, argtwo, code) int player; char *argone; char *argtwo; int code; { int obj, flags; char *oldname; char *givenpwd, ch; /* Find the thing to set the string ON */ if (!argone || !*argone) { notify_player(player, "Set what on what?\r\n"); return; } if ((obj = resolve_object_or_exit(player, argone, 0)) == -1) { notify_player(player, "I don't see that here.\r\n"); return; } if (obj == -2) { notify_player(player, "I don't know which one you mean.\r\n"); return; } if (!controls(player, obj)) { notify_player(player, "You can't do that!\r\n"); return; } #ifdef TIMESTAMPS if (!isplayer(obj)) stamp(obj); #endif /* TIMESTAMPS */ if (code == GENDER && !isplayer(obj)) { notify_player(player, "Only players have gender.\r\n"); return; } if ((code == OARRIVE || code == OLEAVE) && !isplayer(obj)) { notify_player(player, "Only players have teleport strings.\r\n"); return; } if ((code == FAIL || code == SUC) && isplayer(obj)) { notify_player(player, "Players don't have that string.\r\n"); return; } /* We *might* be setting a player name. Gotta be careful */ if (code == NAME) { /* Check out the name */ if (get_int_elt(obj, FLAGS, &flags) == -1) { warning("do_set_string", "cannot get flags"); goto namebomb; } if((flags & TYPE_MASK) == TYP_EXIT) { if (!ok_exit_name(argtwo)) { notify_player(player, "Bad name.\r\n"); return; } } else { if (!ok_name(argtwo)) { notify_player(player, "Bad name.\r\n"); return; } } if ((flags & TYPE_MASK) == TYP_PLAYER) { /* skip to pwd in given name */ givenpwd = argtwo; while (!isspace(*givenpwd) && *givenpwd) givenpwd++; ch = *givenpwd; *givenpwd = '\0'; if (!ok_player_name(argtwo)) { notify_player(player, "You can't give a player that name.\r\n"); return; } *givenpwd = ch; while (isspace(*givenpwd)) givenpwd++; /* Ok. Hack around. */ if (get_str_elt(obj, NAME, &oldname) == -1) { goto namebomb; } /* Skip to password in oldname */ while (!isspace(*oldname) && *oldname) oldname++; while (isspace(*oldname)) oldname++; if (strcmp(oldname, givenpwd) != 0) { notify_player(player, "Wrong password.\r\n"); return; } /* argtwo has a valid name/pwd pair */ } } if(code == OARRIVE) code = FAIL; if(code == OLEAVE) code = SUC; if (set_str_elt(obj, code, argtwo) == -1) goto namebomb; switch (code) { case NAME: notify_player(player, "Name set.\r\n"); break; case GENDER: notify_player(player, "Gender set.\r\n"); break; case DESC: notify_player(player, "Description set.\r\n"); break; default: notify_player(player, "Message set.\r\n"); } return; namebomb: notify_bad(player); return; } voidfunc do_lock(player, argone, argtwo) int player; char *argone; char *argtwo; { int obj, *exp; if (!argone || !*argone || !argtwo || !*argtwo) { notify_player(player, "Lock what to what?\r\n"); return; } if ((obj = resolve_object_or_exit(player, argone, 0)) == -1) { notify_player(player, "I don't see that here.\r\n"); return; } if (obj == -2) { notify_player(player, "I don't know which one you mean.\r\n"); return; } if (!controls(player, obj)) { notify_player(player, "You can't do that!\r\n"); return; } /* OK. We can mess with the lock on this thing. */ exp = bool_parse(player, argtwo); if (exp == NULL) return; /* bool_parse() already told the player off. */ if (set_lock_elt(obj, LOCK, exp) == -1) { notify_bad(player); return; } notify_player(player, "Locked.\r\n"); } voidfunc do_unlock(player, arg) int player; char *arg; { int obj; if (!arg || !*arg) { notify_player(player, "Unlock what?\r\n"); return; } if ((obj = resolve_object_or_exit(player, arg, 0)) == -1) { notify_player(player, "I don't see that here.\r\n"); return; } if (obj == -2) { notify_player(player, "I don't know which on you want to unlock.\r\n"); return; } if (!controls(player, obj)) { notify_player(player, "You can't do that!\r\n"); return; } if (set_lock_elt(obj, LOCK, (int *) NULL) == -1) { notify_bad(player); return; } notify_player(player, "Unlocked.\r\n"); } voidfunc do_open(player, argone, argtwo) int player; char *argone; char *argtwo; { int here, exit, list, dest, flags; int count; extern int total_objects; char *p; #ifdef RESTRICT_BUILDING if (!isbuilder(player) && !iswiz(player)) { notify_player(player, "That command is for authorized builders only.\r\n"); return; } #endif /* RESTRICT_BUILDING */ if (!argone || !*argone) { notify_player(player, "You must specify a name.\r\n"); return; } if (!ok_exit_name(argone)) { notify_player(player, "That's a silly name for an exit!\r\n"); return; } if (get_int_elt(player, LOC, &here) == -1) goto openbomb; #ifndef BUILDING_OK if (!controls(player, here)) { notify_player(player, "You can't open an exit here!\r\n"); return; } #else if (!controls(player, here) && !isbuilder(here)) { notify_player(player, "You can't open an exit here!\r\n"); return; } #endif /* BUILDING_OK */ exit = create_obj(TYP_EXIT); if (set_str_elt(exit, NAME, argone) == -1) goto openbomb; if (set_int_elt(exit, OWNER, player) == -1) goto openbomb; if (set_int_elt(exit, LOC, here) == -1) goto openbomb; if (get_int_elt(here, EXITS, &list) == -1) goto openbomb; if (set_int_elt(exit, NEXT, list) == -1) goto openbomb; if (set_int_elt(here, EXITS, exit) == -1) goto openbomb; #ifdef TIMESTAMPS stamp(exit); #endif /* TIMESTAMPS */ /* Tell the player about this exit */ p = cmdwork; count = 0; strcpy(p, "Exit "); p += 5; count += 5; while (*argone && count < BUFFSIZ - 33) { *p++ = *argone++; count++; } strcpy(p, " opened with number #"); p += 21; p = ty_itoa(p, exit); *p++ = '.'; *p++ = '\r'; *p++ = '\n'; *p = '\0'; notify_player(player, cmdwork); if (argtwo != NULL) { /* Try to link this */ if (strcmp(argtwo, "home") == 0) { dest = -3; } else if (strcmp(argtwo, "here") == 0) { dest = here; } else { if (*argtwo != '#' || !isdigit(argtwo[1])) { notify_player(player, "I don't grok your destination.\r\n"); return; } dest = atoi(argtwo + 1); } notify_player(player, "Trying to link...\r\n"); /* Can we link there? */ if (dest != -3 && !exists_object(dest)) { notify_player(player, "Bad destination.\r\n"); return; } if (dest != -3 && get_int_elt(dest, FLAGS, &flags) == -1) { notify_player(player, "Can't find destination.\r\n"); return; } if (dest != -3 && (TYPE_MASK & flags) != TYP_ROOM) { notify_player(player, "That's not a room!\r\n"); return; } if (!controls(player, dest) && !(flags & LINK_OK)) { notify_player(player, "Can't link to destination.\r\n"); return; } /* OK. We can link there. */ if (set_int_elt(exit, DESTINATION, dest) == -1) goto openbomb; notify_player(player, "Linked.\r\n"); } return; openbomb: notify_bad(player); return; } voidfunc do_link(player, argone, argtwo) int player; char *argone; char *argtwo; { int dest, flags, thing, here, location; int code, foo, exowner; char *msg; if (!argone || !*argone || !argtwo || !*argtwo) { notify_player(player, "Link what to where?\r\n"); return; } if (get_int_elt(player, LOC, &here) == -1) goto linkbomb; /* Find the destination, thing to link to */ if (strcmp(argtwo, "home") == 0) { dest = -3; /* Abstract db ref to home */ } else if (strcmp(argtwo, "here") == 0) { dest = here; } else { if (*argtwo != '#' || !isdigit(argtwo[1])) { notify_player(player, "I don't understand that destination.\r\n"); return; } dest = atoi(argtwo + 1); } /* Can we link there? */ if (dest != -3 && !exists_object(dest)) { notify_player(player, "Bad destination.\r\n"); return; } if (dest != -3 && get_int_elt(dest, FLAGS, &flags) == -1) { notify_player(player, "Can't find destination.\r\n"); return; } if (dest != -3 && (flags & TYPE_MASK) != TYP_ROOM) { notify_player(player, "That's not a room!\r\n"); return; } /* OK. Try to get the thing to link */ if ((thing = resolve_object_or_exit(player, argone)) == -1) { notify_player(player, "I don't see that here.\r\n"); return; } if (thing == -2) { notify_player(player, "I can't tell which one you want to link.\r\n"); return; } if (get_int_elt(thing, FLAGS, &flags) == -1) goto linkbomb; if ((((flags & TYPE_MASK) == TYP_PLAYER) || ((flags & TYPE_MASK) == TYP_THING)) && !controls(player, dest) && !isabode(dest)) { notify_player(player, "You can't link that there!\r\n"); return; } if ((((flags & TYPE_MASK) == TYP_EXIT) || ((flags & TYPE_MASK) == TYP_ROOM)) && !controls(player, dest) && !islinkok(dest)) { notify_player(player, "You can't link that there!\r\n"); return; } /* What sort of thing is it? */ switch (flags & TYPE_MASK) { case TYP_PLAYER: case TYP_THING: if (dest == -3) { notify_player(player, "Paradox in link of object.\r\n"); return; } msg = "Home set.\r\n"; code = HOME; break; case TYP_ROOM: msg = "Dropto set.\r\n"; code = DROPTO; break; case TYP_EXIT: msg = "Linked.\r\n"; code = DESTINATION; /* Check to see if the exit is in the room */ if (get_int_elt(thing, LOC, &location) == -1) goto linkbomb; if (location != here) { notify_player(player, "That exit's not in this room.\r\n"); return; } /* Check that the exit is unlinked */ if (get_int_elt(thing, DESTINATION, &foo) == -1) goto linkbomb; if (foo != -1) { notify_player(player, "That exit is linked.\r\n"); return; } else { if (get_int_elt(thing, OWNER, &exowner) == -1) goto linkbomb; if (exowner != player) { #ifdef RESTRICT_BUILDING if (!isbuilder(player) && !iswiz(player)) { notify_player(player, "Only authorized builders may do that.\r\n"); return; } #endif /* RESTRICT_BUILDING */ } } if (set_int_elt(thing, OWNER, player) == -1) goto linkbomb; notify_player(player, "Trying to link...\r\n"); break; default: notify_player(player, "I don't understand that.\r\n"); warning("do_link", "bad type field detected"); return; } if (!controls(player, thing)) { notify_player(player, "You don't own that!\r\n"); return; } /* Link it up. */ if (set_int_elt(thing, code, dest) == -1) goto linkbomb; notify_player(player, msg); return; linkbomb: notify_bad(player); return; } voidfunc do_unlink(player, arg) int player; char *arg; { int obj, flags, code; char *msg; if (!arg || !*arg) { notify_player(player, "Unlink what?\r\n"); return; } if ((obj = resolve_object_or_exit(player, arg)) == -1) { notify_player(player, "I can't find that.\r\n"); return; } if (obj == -2) { notify_player(player, "I can't tell which one you want to unlink.\r\n"); return; } if (!controls(player, obj)) { notify_player(player, "You can't unlink that!\r\n"); return; } /* Unlink it. */ if (get_int_elt(obj, FLAGS, &flags) == -1) goto unlinkbomb; switch (flags & TYPE_MASK) { case TYP_PLAYER: case TYP_THING: notify_player(player, "Can't unset an object's home!\r\n"); return; case TYP_EXIT: code = DESTINATION; msg = "Exit unlinked.\r\n"; break; case TYP_ROOM: code = DROPTO; msg = "Dropto unset.\r\n"; break; default: notify_player(player, "I don't understand that.\r\n"); return; } if (set_int_elt(obj, code, -1) == -1) goto unlinkbomb; notify_player(player, msg); return; unlinkbomb: notify_bad(player); return; } /* * the next two routines provide @edit service. yay. the code be based on * code found deep within TinyMUSH, with me own argument parser. */ #ifdef EDIT static int parse_attrib(player, s, thing, atr) int player; char *s; int *thing; int *atr; { char buff[1024]; strcpy(buff, s); /* get name up to / */ for (s = buff; *s && (*s != '/'); s++); if (!*s) return (0); *s++ = 0; if ((*thing = resolve_anything(player, buff, iswiz(player))) == -1) return (0); if (*thing == -2) return (-2); if (!exists_object(*thing) || !controls(player, *thing)) return (0); /* rest is attrib name */ if (stringprefix(s, "description")) { *atr = DESC; } else if (stringprefix(s, "success")) { *atr = SUC; } else if (stringprefix(s, "osuccess")) { *atr = OSUC; } else if (stringprefix(s, "fail")) { *atr = FAIL; } else if (stringprefix(s, "ofail")) { *atr = OFAIL; #ifdef DROP_FIELDS } else if (stringprefix(s, "drop")) { *atr = DROP; } else if (stringprefix(s, "odrop")) { *atr = ODROP; #endif /* DROP_FIELDS */ } else if (stringprefix(s, "gender") || stringprefix(s, "sex")) { *atr = GENDER; } else if (stringprefix(s, "name")) { *atr = NAME; } else *atr = 0; if (*atr == 0) return (0); if (((*atr == GENDER) && !isplayer(*thing)) || ((*atr == NAME) && isplayer(*thing))) return (-1); return (1); } voidfunc do_edit(player, it, args) int player; char *it; char *args; { int thing; int atr, d, len; char *r, *s, *val; char dest[1024], arg1[BUFFSIZ], arg2[BUFFSIZ]; if(!it || !*it) { notify_player(player, "Edit what?\r\n"); return; } d = parse_attrib(player, it, &thing, &atr); if (d == 0) { notify_player(player, "No match.\r\n"); return; } else if (d == -2) { notify_player(player, "I can't tell which one you want to edit.\r\n"); return; } else if (d != 1) { notify_player(player, "Permission denied. You can't change that attribute on that object.\r\n"); return; } /* parse arguments */ if (!args || !*args) { notify_player(player, "Nothing to do.\r\n"); return; } d = 0; /* make arg1 */ /* eat this pointer game, xibo ;-) */ /* Thanks, it was delicious. */ while(d < (BUFFSIZ - 32) && args[0] != 0){ if(args[0] != ',' && args[0] != '\\'){ arg1[d] = *args++; d++; } else { if(args[0] == '\\' && args[1] != ','){ arg1[d] = *args++; d++; } else { if(args[0] == '\\' && args[1] == ','){ arg1[d] = args[1]; args += 2; d++; } else { arg1[d] = 0; d++; args++; break; } } } } arg1[d] = 0; /* make arg2 */ d = 0; while(d < (BUFFSIZ - 32) && args[d] != 0){ arg2[d] = args[d]; d++; } arg2[d] = 0; if (arg1[0] == 0) { notify_player(player, "Nothing to do.\r\n"); return; } val = arg1; r = (arg2[0]) ? arg2 : (char *) ""; /* replace all occurances of val with r */ if (get_str_elt(thing, atr, &s) == -1) { warning("do_edit", "bad object ref"); notify_bad(player); return; } if (!s || !*s) { notify_player(player, "Nothing to do.\r\n"); return; } len = strlen(val); for (d = 0; (d < 1000) && *s;) if (strncmp(val, s, len) == 0) { if ((d + strlen(r)) < 1000) { strcpy(dest + d, r); d += strlen(r); s += len; } else dest[d++] = *s++; } else dest[d++] = *s++; dest[d++] = 0; dest[BUFFSIZ - 1] = '\0'; if (set_str_elt(thing, atr, dest) == -1) { warning("do_edit", "failed to store revised string"); notify_bad(player); return; } switch (atr) { case DESC: notify_player(player, "Description set.\r\n"); break; case GENDER: notify_player(player, "Gender set.\r\n"); break; case NAME: notify_player(player, "Name set.\r\n"); break; default: notify_player(player, "Message set.\r\n"); } #ifdef TIMESTAMPS if (!isplayer(thing)) { stamp(thing); } #endif /* TIMESTAMPS */ } #endif /* EDIT */