/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ /* configure all options BEFORE including system stuff. */ #include "config.h" #include "mud.h" #include "vars.h" #include "match.h" /* create new objects for our mini-universe. */ static int buildobj(char *who, char *aswho, char *name, char *desc); static int buildplayer(char *who, char *aswho, char *name, char *loc, char *pass); static int build_canlink(char *who, char *aswho, char *to, char *from, int remoteflg); static int build_goodname(char *nam, int exitflag); static int buildexit(char *who, char *aswho, char *name, char *from, char *to); static int buildroom(char *who, char *aswho, char *name, char *exnam, char *retnam); static int buildlink(char *who, char *aswho, char *name, char *from, char *to); /* create a standard-carrying-around-type thang */ static int buildobj (who, aswho, name, desc) char *who; char *aswho; char *name; char *desc; { char nuf[MAXOID]; char hm[MAXOID]; char *op; if (!build_goodname (name, 0)) { say (who, "bad name.\n", (char *) 0); return (UERR_ILLASGN); } if (ut_objnew (who, nuf)) return (UERR_FATAL); eval_cmd_returnstr (nuf); /* add the object to player's inventory */ if (ut_listadd (who, who, var_cont, nuf)) return (UERR_FATAL); /* set owner */ op = ut_getatt (aswho, 0, typ_list, var_owner, (char *) 0); if (op != (char *) 0 && ut_set (who, nuf, typ_list, var_owner, op)) return (UERR_FATAL); /* set location of the object (on the player) */ if (ut_set (who, nuf, typ_obj, var_loc, who)) return (UERR_FATAL); /* set home of the object (on the player) */ (void) strcpy (hm, who); ut_delocaliz (hm); if (ut_set (who, nuf, typ_obj, var_home, hm)) return (UERR_FATAL); /* set name if one given */ if (name != (char *) 0 && ut_set (who, nuf, typ_str, var_nam, name)) return (UERR_FATAL); /* set desc if one given */ if (desc != (char *) 0 && ut_set (who, nuf, typ_str, var_desc, desc)) return (UERR_FATAL); if (run_level () == 0) say (who, "Created object ", nuf, ".\n", (char *) 0); return (UERR_NONE); } /* make a new person! */ static int buildplayer (who, aswho, name, loc, pass) char *who; char *aswho; char *name; char *loc; char *pass; { char nuf[MAXOID]; char hm[MAXOID]; char *limbo; if (!ut_flagged (aswho, var_wiz)) { say (who, "Only a wizard can bring forth new life.\n", (char *) 0); return (UERR_PERM); } if (ut_objnew (who, nuf)) return (UERR_FATAL); eval_cmd_returnstr (nuf); /* add the object to room */ if (ut_listadd (who, loc, var_ply, nuf)) return (UERR_FATAL); /* set owner - player owns itself ! */ if (ut_set (who, nuf, typ_list, var_owner, nuf)) return (UERR_FATAL); /* set password */ if (pass == (char *) 0) { /* set an empty password */ if (ut_set (who, nuf, typ_str, var_pass, "")) return (UERR_FATAL); } else { if (ut_setpass (nuf, pass)) return (UERR_FATAL); } /* make it a player */ if (ut_set (who, nuf, typ_flag, var_isplay, "")) return (UERR_FATAL); /* set location of the object (in the room) */ if (ut_set (who, nuf, typ_obj, var_loc, loc)) return (UERR_FATAL); /* set home for the player (limbo) */ limbo = ut_getatt (system_object, 0, typ_obj, var_syslimbo, (char *) 0); if (limbo == (char *) 0) { plogf ("build player %s: no limbo; home is room %s\n", nuf, loc); say (who, "no limbo; player home is here\n", (char *) 0); limbo = loc; } (void) strcpy (hm, limbo); ut_delocaliz (hm); if (ut_set (who, nuf, typ_obj, var_home, hm)) return (UERR_FATAL); /* set name if one given */ if (name != (char *) 0 && ut_set (who, nuf, typ_str, var_nam, name)) return (UERR_FATAL); if (run_level () == 0) say (who, "Created player ", nuf, ".\n", (char *) 0); return (UERR_NONE); } static int build_canlink (who, aswho, to, from, remoteflg) char *who; char *aswho; char *to; char *from; int remoteflg; { int wiz = ut_flagged (aswho, var_wiz); /* If not to 'home', check the dest busily */ if (!strcmp (to, "home")) return (1); if (remoteflg && !wiz && !cache_check (to)) { /* Try to make a remote link */ if (xact_addlink (to, from, aswho)) { say (who, "No such destination locally. Could not make ", "remote link to ", to, ".\n", (char *) 0); return (0); } } else { /* is the destination link ok ? */ if (!wiz && !ut_isobjown (aswho, to) && bool_locked (aswho, to, (char *) 0, var_link, 1)) { say (who, "Cannot link to ", to, ".\n", (char *) 0); return (0); } /* is it really a room ? */ if (!wiz && !ut_flagged (to, var_isroom)) { say (who, "You cannot link into a non-room.\n", (char *) 0); return (0); } } return (1); } /* check if a string is a valid thing-name. Basically, nothing can start with and @ character. */ static int build_goodname (nam, exitflag) char *nam; int exitflag; { int ok = 1; if (nam == (char *) 0) return (0); /* Don't let people build things that will confuse the matcher. */ if (strcmp (nam, "here") == 0 || strcmp (nam, "me") == 0) return (0); if (exitflag) { /* Check an exit name */ if (*nam == '#') return (0); while ((nam = index (nam, ';')) != (char *) 0 && ok) ok = (*(++nam) != '#'); return (ok); } else { /* Check other stuff */ return (*nam != '#'); } } /* create an exit */ static int buildexit (who, aswho, name, from, to) char *who; char *aswho; char *name; char *to; char *from; { char nuf[MAXOID]; char *op; if (!build_goodname (name, 1)) { say (who, "bad name.\n", (char *) 0); return (UERR_ILLASGN); } /* do we own this room ? */ if (ut_flagged (aswho, var_wiz) == 0 && !ut_isobjown (aswho, from)) { say (who, "Cannot open exit. Not owner.\n", (char *) 0); return (UERR_PERM); } if (!strcmp ("here", to)) to = ut_loc (run_actor ()); if (to != (char *) 0 && !build_canlink (who, aswho, to, from, 1)) { say (who, "Exit not created.\n", (char *) 0); return (UERR_PERM); } if (ut_objnew (who, nuf)) return (UERR_FATAL); eval_cmd_returnstr (nuf); /* chown it inherited from effective user-id */ op = ut_getatt (aswho, 0, typ_list, var_owner, (char *) 0); if (op != (char *) 0 && ut_set (who, nuf, typ_list, var_owner, op)) return (UERR_FATAL); if (run_level () == 0) say (who, "Opened exit ", nuf, ".\n", (char *) 0); /* name it */ if (name != (char *) 0 && ut_set (who, nuf, typ_str, var_nam, name)) return (UERR_FATAL); /* link it to its destination - TODO - add checking, etc. */ if (to != (char *) 0) { if (ut_set (who, nuf, typ_obj, var_dest, to)) return (UERR_FATAL); if (run_level () == 0) say (who, "Linked exit to ", to, ".\n", (char *) 0); } /* set the exits location */ if (ut_set (who, nuf, typ_obj, var_loc, from)) return (UERR_FATAL); /* add the object to room's exit list */ if (ut_listadd (who, from, var_xit, nuf)) return (UERR_FATAL); return (UERR_NONE); } /* create a room */ static int buildroom (who, aswho, name, exnam, retnam) char *who; char *aswho; char *name; char *exnam; char *retnam; { char *op; char nuf[MAXOID]; int xx; if (!build_goodname (name, 0)) { say (who, "bad room name.\n", (char *) 0); return (UERR_ILLASGN); } if ((exnam != (char *) 0 && !build_goodname (exnam, 1)) || (retnam != (char *) 0 && !build_goodname (retnam, 1))) { say (who, "bad exit name.\n", (char *) 0); return (UERR_ILLASGN); } if (ut_objnew (who, nuf)) return (UERR_FATAL); /* chown it */ op = ut_getatt (aswho, 0, typ_list, var_owner, (char *) 0); if (op != (char *) 0 && ut_set (who, nuf, typ_list, var_owner, op)) return (UERR_FATAL); /* make it a room */ if (ut_set (who, nuf, typ_flag, var_isroom, "")) return (UERR_FATAL); /* name it */ if (name != (char *) 0 && ut_set (who, nuf, typ_str, var_nam, name)) return (UERR_FATAL); if (exnam != (char *) 0 && (xx = buildexit (who, aswho, exnam, ut_loc (who), nuf)) != UERR_NONE) return (xx); if (retnam != (char *) 0 && (xx = buildexit (who, aswho, retnam, nuf, ut_loc (who))) != UERR_NONE) return (xx); /* down here to return the OID of the room, not the exits */ eval_cmd_returnstr (nuf); if (run_level () == 0) say (who, "Dug room ", nuf, ".\n", (char *) 0); return (UERR_NONE); } /* new destination for an existing exit */ static int buildlink (who, aswho, name, from, to) char *who; char *aswho; char *name; char *to; char *from; { char nuf[MAXOID]; if (matchexit (who, name, from, MTCH_EXACT | MTCH_NONLOC | MTCH_UNIQ, nuf)) return (UERR_NOMATCH); /* do we own this exit ? */ if (ut_flagged (aswho, var_wiz) == 0 && !ut_isobjown (aswho, nuf)) { say (who, "Cannot link exit. Not owner.\n", (char *) 0); return (UERR_PERM); } if (to != (char *) 0 && !build_canlink (who, aswho, to, from, 1)) { say (who, "Cannot link exit. Permission denied.\n", (char *) 0); return (UERR_PERM); } if (to != (char *) 0) { if (ut_set (who, nuf, typ_obj, var_dest, to)) return (UERR_FATAL); if (run_level () == 0) say (who, "Linked exit to ", to, ".\n", (char *) 0); } return (UERR_NONE); } /* figure out what the hell the goober is trying to do - modularize */ /* ARGSUSED */ int cmd_build (int ac, char *av[], char *who, char *aswho) { if (ac < 2) { say (who, av[0], " a what?\n", (char *) 0); return (UERR_ARGCNT); } if (ac >= 2 && !strncmp (av[1], "object", strlen (av[1]))) { char *name = (char *) 0; char *desc = (char *) 0; if (ac > 2) name = av[2]; if (ac > 3) desc = av[3]; return (buildobj (who, aswho, name, desc)); } if (ac >= 2 && !strncmp (av[1], "room", strlen (av[1]))) { char *name = (char *) 0; char *exnam = (char *) 0; char *retnam = (char *) 0; if (ac > 2) name = av[2]; if (ac > 3) exnam = av[3]; if (ac > 4) retnam = av[4]; return (buildroom (who, aswho, name, exnam, retnam)); } if (ac >= 2 && !strncmp (av[1], "exit", strlen (av[1]))) { char *name = (char *) 0; char *dest = (char *) 0; if (ac < 4) { say (who, "usage: ", av[0], " exit name destination-room\n", (char *) 0); return (UERR_ARGCNT); } name = av[2]; dest = av[3]; return (buildexit (who, aswho, name, ut_loc (who), dest)); } if (ac >= 2 && !strncmp (av[1], "link", strlen (av[1]))) { char *name = (char *) 0; char *dest = (char *) 0; if (ac < 4) { say (who, "usage: ", av[0], " link existing-exit destination-room\n", (char *) 0); return (UERR_ARGCNT); } name = av[2]; dest = av[3]; return (buildlink (who, aswho, name, ut_loc (who), dest)); } if (ac >= 2 && !strncmp (av[1], "player", strlen (av[1]))) { char *name = (char *) 0; char *pass = (char *) 0; if (ac > 2) name = av[2]; if (ac > 3) pass = av[3]; return (buildplayer (who, aswho, name, ut_loc (who), pass)); } if (!strcmp (av[1], "help")) { say (who, av[0], " object [name] [description]\n", (char *) 0); say (who, av[0], " room [name] [exit-to-name] [exit-back-name]\n", (char *) 0); say (who, av[0], " exit name destination-room\n", (char *) 0); say (who, av[0], " link existing-exit destination-room\n", (char *) 0); say (who, av[0], " player name [password]\n", (char *) 0); return (UERR_NONE); } say (who, "I don't understand what you want to ", av[0], "\n", (char *) 0); return (UERR_ARGCNT); }