/*
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);
}