/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ #ifndef lint static char RCSid[] = "$Header: /usr/users/mjr/hacks/umud/CMD/RCS/build.c,v 1.6 91/09/19 12:55:31 mjr Exp $"; #endif /* 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 build_goodname(); /* 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(1); } /* get an object-ID for it and make it non-local */ if(ut_objnew(who,nuf,0)) return(1); /* add the object to player's inventory */ if(ut_listadd(who,who,var_cont,nuf)) return(1); /* 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(1); /* set location of the object (on the player) */ if(ut_set(who,nuf,typ_obj,var_loc,who)) return(1); /* 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(1); /* set name if one given */ if(name != (char *)0 && ut_set(who,nuf,typ_str,var_nam,name)) return(1); /* set desc if one given */ if(desc != (char *)0 && ut_set(who,nuf,typ_str,var_desc,desc)) return(1); if(run_level() == 0) say(who,"Created object ",nuf,".\n",(char *)0); return(0); } /* 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(1); } /* get an object-ID for it and make it non-local */ if(ut_objnew(who,nuf,0)) return(1); /* add the object to room */ if(ut_listadd(who,loc,var_ply,nuf)) return(1); /* set owner - player owns itself ! */ if(ut_set(who,nuf,typ_list,var_owner,nuf)) return(1); /* set password */ if(pass == (char *)0) { /* set an empty password */ if(ut_set(who,nuf,typ_str,var_pass,"")) return(1); } else { if(ut_setpass(nuf,pass)) return(1); } /* make it a player */ if(ut_set(who,nuf,typ_flag,var_isplay,"")) return(1); /* set location of the object (in the room) */ if(ut_set(who,nuf,typ_obj,var_loc,loc)) return(1); /* 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(1); /* set name if one given */ if(name != (char *)0 && ut_set(who,nuf,typ_str,var_nam,name)) return(1); if(run_level() == 0) say(who,"Created player ",nuf,".\n",(char *)0); return(0); } 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]; int wiz; char *op; if(!build_goodname(name,1)){ say(who,"bad name.\n",(char *)0); return(1); } /* do we own this room ? */ if((wiz = ut_flagged(aswho,var_wiz)) == 0 && !ut_isobjown(aswho,from)) { say(who,"Cannot open exit. Not owner.\n",(char *)0); return(1); } 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(1); } if(ut_objnew(who,nuf,1)) return(1); /* 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(1); 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(1); /* link it to its destination - TODO - add checking, etc. */ if(to != (char *)0) { if(ut_set(who,nuf,typ_obj,var_dest,to)) return(1); 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(1); /* add the object to room's exit list */ if(ut_listadd(who,from,var_xit,nuf)) return(1); return(0); } /* 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]; if(!build_goodname(name,0)){ say(who,"bad room name.\n",(char *)0); return(1); } if((exnam != (char *)0 && !build_goodname(exnam,1)) || (retnam != (char *)0 && !build_goodname(retnam,1))){ say(who,"bad exit name.\n",(char *)0); return(1); } if(ut_objnew(who,nuf,1)) return(1); /* 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(1); /* make it a room */ if(ut_set(who,nuf,typ_flag,var_isroom,"")) return(1); /* name it */ if(name != (char *)0 && ut_set(who,nuf,typ_str,var_nam,name)) return(1); if(exnam != (char *)0 && buildexit(who,aswho,exnam,ut_loc(who),nuf)) return(1); if(retnam != (char *)0 && buildexit(who,aswho,retnam,nuf,ut_loc(who))) return(1); if(run_level() == 0) say(who,"Dug room ",nuf,".\n",(char *)0); return(0); } /* 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]; int wiz; if(matchexit(who,name,from,MTCH_EXACT|MTCH_NONLOC|MTCH_UNIQ,nuf)) return (1); /* do we own this exit ? */ if((wiz = ut_flagged(aswho,var_wiz)) == 0 && !ut_isobjown(aswho,nuf)) { say(who,"Cannot link exit. Not owner.\n",(char *)0); return(1); } if(to != (char *)0 && !build_canlink(who,aswho,to,from,1)){ say(who,"Cannot link exit. Permission denied.\n",(char *)0); return(1); } if(to != (char *)0) { if(ut_set(who,nuf,typ_obj,var_dest,to)) return(1); if(run_level() == 0) say(who,"Linked exit to ",to,".\n",(char *)0); } return(0); } /* figure out what the hell the goober is trying to do - modularize */ /* ARGSUSED */ cmd_build(ac,av,who,aswho) int ac; char *av[]; char *who; char *aswho; { if(ac < 2) { say(who,av[0]," a what?\n",(char *)0); return(1); } 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(1); } 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(1); } 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(0); } say(who,"I don't understand what you want to ",av[0],"\n",(char *)0); return(1); }