Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!cornell!uw-beaver!tektronix!tekgen!tekred!games
From: games@tekred.TEK.COM
Newsgroups: comp.sources.games
Subject: v05i092: monster - multiuser adventure game for VMS, Part05/06
Message-ID: <3323@tekred.TEK.COM>
Date: 30 Nov 88 20:12:16 GMT
Sender: billr@tekred.TEK.COM
Lines: 2511
Approved: billr@saab.CNA.TEK.COM
Submitted by: Richard Skrenta
Comp.sources.games: Volume 5, Issue 92
Archive-name: monster/Part05
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh 'mon3.pas' <<'END_OF_FILE'
X
X{ disown everything a player owns }
X
Xprocedure disown_user(s:string);
Xvar
X n: integer;
X i: integer;
X tmp: string;
X theuser: string;
X
Xbegin
X if length(s) > 0 then begin
X if debug then
X writeln('calling lookup_user with ',s);
X if not lookup_user(n,s) then
X writeln('User not in log info, attempting to disown anyway.');
X
X theuser := user.idents[n];
X
X { first disown all their rooms }
X
X getown;
X freeown;
X for i := 1 to maxroom do
X if own.idents[i] = theuser then begin
X getown;
X own.idents[i] := '*';
X putown;
X
X getroom(i);
X tmp := here.nicename;
X here.owner := '*';
X putroom;
X
X writeln('Disowned room ',tmp);
X end;
X writeln;
X
X getobjown;
X freeobjown;
X getobjnam;
X freeobjnam;
X for i := 1 to maxroom do
X if objown.idents[i] = theuser then begin
X getobjown;
X objown.idents[i] := '*';
X putobjown;
X
X tmp := objnam.idents[i];
X writeln('Disowned object ',tmp);
X end;
X end else
X writeln('No user specified.');
Xend;
X
Xprocedure move_asleep;
Xvar
X pname,rname:string; { player & room names }
X newroom,n: integer; { room number & player slot number }
X
Xbegin
X grab_line('Player name? ',pname);
X grab_line('Room name? ',rname);
X if lookup_user(n,pname) then begin
X if lookup_room(newroom,rname) then begin
X getindex(I_ASLEEP);
X freeindex;
X if indx.free[n] then begin
X getint(N_LOCATION);
X anint.int[n] := newroom;
X putint;
X writeln('Player moved.');
X end else
X writeln('That player is not asleep.');
X end else
X writeln('No such room found.');
X end else
X writeln('User not found.');
Xend;
X
X
Xprocedure system_help;
X
Xbegin
X writeln;
X writeln('B Add description blocks');
X writeln('D Disown ');
X writeln('E Exit (same as quit)');
X writeln('I Add Integer records');
X writeln('K Kill ');
X writeln('L Add one liner records');
X writeln('M Move a player who is asleep (not playing now)');
X writeln('O Add object records');
X writeln('P Write a distribution list of players');
X writeln('Q Quit (same as exit)');
X writeln('R Add rooms');
X writeln('V View current sizes/usage');
X writeln('? This list');
X writeln;
Xend;
X
X
X{ *************** FIX_STUFF ******************** }
X
Xprocedure fix_stuff;
X
Xbegin
Xend;
X
X
Xprocedure do_system(s: string);
Xvar
X prompt: string;
X done: boolean;
X cmd: char;
X n: integer;
X p: string;
X
Xbegin
X if privd then begin
X log_action(c_system,0);
X prompt := 'System> ';
X done := false;
X repeat
X repeat
X grab_line(prompt,s);
X s := slead(s);
X until length(s) > 0;
X s := lowcase(s);
X cmd := s[1];
X
X n := 0;
X p := '';
X if length(s) > 1 then begin
X p := slead( substr(s,2,length(s)-1) );
X n := number(p)
X end;
X if debug then begin
X writeln('p = ',p);
X end;
X
X case cmd of
X 'h','?': system_help;
X '1': fix_stuff;
X{remove a user} 'k': kill_user(p);
X{disown} 'd': disown_user(p);
X{dist list of players} 'p': dist_list;
X{move where user will wakeup} 'm': move_asleep;
X{add rooms} 'r': begin
X if n > 0 then begin
X addrooms(n);
X end else
X writeln('To add rooms, say R <# to add>');
X end;
X{add ints} 'i': begin
X if n > 0 then begin
X addints(n);
X end else
X writeln('To add integers, say I <# to add>');
X end;
X{add description blocks} 'b': begin
X if n > 0 then begin
X addblocks(n);
X end else
X writeln('To add description blocks, say B <# to add>');
X end;
X{add objects} 'o': begin
X if n > 0 then begin
X addobjects(n);
X end else
X writeln('To add object records, say O <# to add>');
X end;
X{add one-liners} 'l': begin
X if n > 0 then begin
X addlines(n);
X end else
X writeln('To add one liner records, say L <# to add>');
X end;
X{view current stats} 'v': begin
X system_view;
X end;
X{quit} 'q','e': done := true;
X otherwise writeln('-- bad command, type ? for a list.');
X end;
X until done;
X log_event(myslot,E_SYSDONE,0,0);
X end else
X writeln('Only the Monster Manger may enter system maintenance mode.');
Xend;
X
X
Xprocedure do_version(s: string);
X
Xbegin
X writeln('Monster, a multiplayer adventure game where the players create the world');
X writeln('and make the rules.');
X writeln;
X writeln('Written by Rich Skrenta at Northwestern University, 1988.');
Xend;
X
X
Xprocedure rebuild_system;
Xvar
X i,j: integer;
X
Xbegin
X writeln('Creating index file 1-6');
X for i := 1 to 7 do begin
X { 1 is blocklist
X 2 is linelist
X 3 is roomlist
X 4 is playeralloc
X 5 is player awake (playing game)
X 6 are objects
X 7 is intfile }
X
X locate(indexfile,i);
X for j := 1 to maxindex do
X indexfile^.free[j] := true;
X indexfile^.indexnum := i;
X indexfile^.top := 0; { none of each to start }
X indexfile^.inuse := 0;
X put(indexfile);
X end;
X
X
X writeln('Initializing roomfile with 10 rooms');
X addrooms(10);
X
X writeln('Initializing block file with 10 description blocks');
X addblocks(10);
X
X writeln('Initializing line file with 10 lines');
X addlines(10);
X
X writeln('Initializing object file with 10 objects');
X addobjects(10);
X
X
X writeln('Initializing namfile 1-8');
X for j := 1 to 8 do begin
X locate(namfile,j);
X namfile^.validate := j;
X namfile^.loctop := 0;
X for i := 1 to maxroom do begin
X namfile^.idents[i] := '';
X end;
X put(namfile);
X end;
X
X writeln('Initializing eventfile');
X for i := 1 to numevnts + 1 do begin
X locate(eventfile,i);
X eventfile^.validat := i;
X eventfile^.point := 1;
X put(eventfile);
X end;
X
X writeln('Initializing intfile');
X for i := 1 to 6 do begin
X locate(intfile,i);
X intfile^.intnum := i;
X put(intfile);
X end;
X
X getindex(I_INT);
X for i := 1 to 6 do
X indx.free[i] := false;
X indx.top := 6;
X indx.inuse := 6;
X putindex;
X
X { Player log records should have all their slots initially,
X they don't have to be allocated because they use namrec
X and intfile for their storage; they don't have their own
X file to allocate
X }
X getindex(I_PLAYER);
X indx.top := maxplayers;
X putindex;
X getindex(I_ASLEEP);
X indx.top := maxplayers;
X putindex;
X
X writeln('Creating the Great Hall');
X createroom('Great Hall');
X getroom(1);
X here.owner := '';
X putroom;
X getown;
X own.idents[1] := '';
X putown;
X
X writeln('Creating the Void');
X createroom('Void'); { loc 2 }
X writeln('Creating the Pit of Fire');
X createroom('Pit of Fire'); { loc 3 }
X { note that these are NOT public locations }
X
X
X writeln('Use the SYSTEM command to view and add capacity to the database');
X writeln;
Xend;
X
X
Xprocedure special(s: string);
X
Xbegin
X if (s = 'rebuild') and (privd) then begin
X if REBUILD_OK then begin
X writeln('Do you really want to destroy the entire universe?');
X readln(s);
X if length(s) > 0 then
X if substr(lowcase(s),1,1) = 'y' then
X rebuild_system;
X end else
X writeln('REBUILD is disabled; you must recompile.');
X end else if s = 'version' then begin
X { Don't take this out please... }
X writeln('Monster, written by Rich Skrenta at Northwestern University, 1988.');
X end else if s = 'quit' then
X done := true;
Xend;
X
X
X{ put an object in this location
X if returns false, there were no more free object slots here:
X in other words, the room is too cluttered, and cannot hold any
X more objects
X}
Xfunction place_obj(n: integer;silent:boolean := false): boolean;
Xvar
X found: boolean;
X i: integer;
X
Xbegin
X if here.objdrop = 0 then
X getroom
X else
X getroom(here.objdrop);
X i := 1;
X found := false;
X while (i <= maxobjs) and (not found) do begin
X if here.objs[i] = 0 then
X found := true
X else
X i := i + 1;
X end;
X place_obj := found;
X if found then begin
X here.objs[i] := n;
X here.objhide[i] := 0;
X putroom;
X
X gethere;
X
X
X { if it bounced somewhere else then tell them }
X
X if (here.objdrop <> 0) and (here.objdest <> 0) then
X log_event(0,E_BOUNCEDIN,here.objdest,n,'',here.objdrop);
X
X
X if not(silent) then begin
X if here.objdesc <> 0 then
X print_subs(here.objdesc,obj_part(n))
X else
X writeln('Dropped.');
X end;
X end else
X freeroom;
Xend;
X
X
X{ remove an object from this room }
Xfunction take_obj(objnum,slot: integer): boolean;
X
Xbegin
X getroom;
X if here.objs[slot] = objnum then begin
X here.objs[slot] := 0;
X here.objhide[slot] := 0;
X take_obj := true;
X end else
X take_obj := false;
X putroom;
Xend;
X
X
Xfunction can_hold: boolean;
X
Xbegin
X if find_numhold < maxhold then
X can_hold := true
X else
X can_hold := false;
Xend;
X
X
Xfunction can_drop: boolean;
X
Xbegin
X if find_numobjs < maxobjs then
X can_drop := true
X else
X can_drop := false;
Xend;
X
X
Xfunction find_hold(objnum: integer;slot:integer := 0): integer;
Xvar
X i: integer;
X
Xbegin
X if slot = 0 then
X slot := myslot;
X i := 1;
X find_hold := 0;
X while i <= maxhold do begin
X if here.people[slot].holding[i] = objnum then
X find_hold := i;
X i := i + 1;
X end;
Xend;
X
X
X
X{ put object number n into the player's inventory; returns false if
X he's holding too many things to carry another }
X
Xfunction hold_obj(n: integer): boolean;
Xvar
X found: boolean;
X i: integer;
X
Xbegin
X getroom;
X i := 1;
X found := false;
X while (i <= maxhold) and (not found) do begin
X if here.people[myslot].holding[i] = 0 then
X found := true
X else
X i := i + 1;
X end;
X hold_obj := found;
X if found then begin
X here.people[myslot].holding[i] := n;
X putroom;
X
X getobj(n);
X freeobj;
X hold_kind[i] := obj.kind;
X end else
X freeroom;
Xend;
X
X
X
X{ remove an object (hold) from the player record, given the slot that
X the object is being held in }
X
Xprocedure drop_obj(slot: integer;pslot: integer := 0);
X
Xbegin
X if pslot = 0 then
X pslot := myslot;
X getroom;
X here.people[pslot].holding[slot] := 0;
X putroom;
X
X hold_kind[slot] := 0;
Xend;
X
X
X
X{ maybe drop something I'm holding if I'm hit }
X
Xprocedure maybe_drop;
Xvar
X i: integer;
X objnum: integer;
X s: string;
X
Xbegin
X i := 1 + (rnd100 mod maxhold);
X objnum := here.people[myslot].holding[i];
X
X if (objnum <> 0) and (mywield <> objnum) and (mywear <> objnum) then begin
X { drop something }
X
X drop_obj(i);
X if place_obj(objnum,TRUE) then begin
X getobjnam;
X freeobjnam;
X writeln('The ',objnam.idents[objnum],' has slipped out of your hands.');
X
X
X s := objnam.idents[objnum];
X log_event(myslot,E_SLIPPED,0,0,s);
X end else
X writeln('%error in maybe_drop; unsuccessful place_obj; notify Monster Manager');
X
X end;
Xend;
X
X
X
X{ return TRUE if the player is allowed to program the object n
X if checkpub is true then obj_owner will return true if the object in
X question is public }
X
Xfunction obj_owner(n: integer;checkpub: boolean := FALSE):boolean;
X
Xbegin
X getobjown;
X freeobjown;
X if (objown.idents[n] = userid) or (privd) then begin
X obj_owner := true;
X end else if (objown.idents[n] = '') and (checkpub) then begin
X obj_owner := true;
X end else begin
X obj_owner := false;
X end;
Xend;
X
X
Xprocedure do_duplicate(s: string);
Xvar
X objnum: integer;
X
Xbegin
X if length(s) > 0 then begin
X if not is_owner(location,TRUE) then begin
X { only let them make things if they're on their home turf }
X writeln('You may only create objects when you are in one of your own rooms.');
X end else begin
X if lookup_obj(objnum,s) then begin
X if obj_owner(objnum,TRUE) then begin
X if not(place_obj(objnum,TRUE)) then
X { put the new object here }
X writeln('There isn''t enough room here to make that.')
X else begin
X{ keep track of how many there } getobj(objnum);
X{ are in existence } obj.numexist := obj.numexist + 1;
X putobj;
X
X log_event(myslot,E_MADEOBJ,0,0,
X myname + ' has created an object here.');
X writeln('Object created.');
X end;
X end else
X writeln('Power to create that object belongs to someone else.');
X end else
X writeln('There is no object by that name.');
X end;
X end else
X writeln('To duplicate an object, type DUPLICATE .');
Xend;
X
X
X{ make an object }
Xprocedure do_makeobj(s: string);
Xvar
X objnum: integer;
X
Xbegin
X gethere;
X if checkhide then begin
X if not is_owner(location,TRUE) then begin
X writeln('You may only create objects when you are in one of your own rooms.');
X end else if s <> '' then begin
X if length(s) > shortlen then
X writeln('Please limit your object names to ',shortlen:1,' characters.')
X else if exact_obj(objnum,s) then begin { object already exits }
X writeln('That object already exits. If you would like to make another copy of it,');
X writeln('use the DUPLICATE command.');
X end else begin
X if debug then
X writeln('%beggining to create object');
X if find_numobjs < maxobjs then begin
X if alloc_obj(objnum) then begin
X if debug then
X writeln('%alloc_obj successful');
X getobjnam;
X objnam.idents[objnum] := lowcase(s);
X putobjnam;
X if debug then
X writeln('%getobjnam completed');
X getobjown;
X objown.idents[objnum] := userid;
X putobjown;
X if debug then
X writeln('%getobjown completed');
X
X getobj(objnum);
X obj.onum := objnum;
X obj.oname := s; { name of object }
X obj.kind := 0; { bland object }
X obj.linedesc := DEFAULT_LINE;
X obj.actindx := 0;
X obj.examine := 0;
X obj.numexist := 1;
X obj.home := 0;
X obj.homedesc := 0;
X
X obj.sticky := false;
X obj.getobjreq := 0;
X obj.getfail := 0;
X obj.getsuccess := DEFAULT_LINE;
X
X obj.useobjreq := 0;
X obj.uselocreq := 0;
X obj.usefail := DEFAULT_LINE;
X obj.usesuccess := DEFAULT_LINE;
X
X obj.usealias := '';
X obj.reqalias := false;
X obj.reqverb := false;
X
X if s[1] in ['a','A','e','E','i','I','o','O','u','U'] then
X obj.particle := 2 { an }
X else
X obj.particle := 1; { a }
X
X obj.d1 := 0;
X obj.d2 := 0;
X obj.exp3 := 0;
X obj.exp4 := 0;
X obj.exp5 := DEFAULT_LINE;
X obj.exp6 := DEFAULT_LINE;
X putobj;
X
X
X if debug then
X writeln('putobj completed');
X end;
X { else: alloc_obj prints errors by itself }
X if not(place_obj(objnum,TRUE)) then
X { put the new object here }
X writeln('%error in makeobj - could not place object; notify the Monster Manager.')
X else begin
X log_event(myslot,E_MADEOBJ,0,0,
X myname + ' has created an object here.');
X writeln('Object created.');
X end;
X
X end else
X writeln('This place is too crowded to create any more objects. Try somewhere else.');
X end;
X end else
X writeln('To create an object, type MAKE .');
X end;
Xend;
X
X{ remove the type block for an object; all instances of the object must
X be destroyed first }
X
Xprocedure do_unmake(s: string);
Xvar
X n: integer;
X tmp: string;
X
Xbegin
X if not(is_owner(location,TRUE)) then
X writeln('You must be in one of your own rooms to UNMAKE an object.')
X else if lookup_obj(n,s) then begin
X tmp := obj_part(n);
X { this will do a getobj(n) for us }
X
X if obj.numexist = 0 then begin
X delete_obj(n);
X
X log_event(myslot,E_UNMAKE,0,0,tmp);
X writeln('Object removed.');
X end else
X writeln('You must DESTROY all instances of the object first.');
X end else
X writeln('There is no object here by that name.');
Xend;
X
X
X{ destroy a copy of an object }
X
Xprocedure do_destroy(s: string);
Xvar
X slot,n: integer;
X
Xbegin
X if length(s) = 0 then
X writeln('To destroy an object you own, type DESTROY .')
X else if not is_owner(location,TRUE) then
X writeln('You must be in one of your own rooms to destroy an object.')
X else if parse_obj(n,s) then begin
X getobjown;
X freeobjown;
X if (objown.idents[n] <> userid) and (objown.idents[n] <> '') and
X (not privd) then
X writeln('You must be the owner of an object to destroy it.')
X else if obj_hold(n) then begin
X slot := find_hold(n);
X drop_obj(slot);
X
X log_event(myslot,E_DESTROY,0,0,
X myname + ' has destroyed ' + obj_part(n) + '.');
X writeln('Object destroyed.');
X
X getobj(n);
X obj.numexist := obj.numexist - 1;
X putobj;
X end else if obj_here(n) then begin
X slot := find_obj(n);
X if not take_obj(n,slot) then
X writeln('Someone picked it up before you could destroy it.')
X else begin
X log_event(myslot,E_DESTROY,0,0,
X myname + ' has destroyed ' + obj_part(n,FALSE) + '.');
X writeln('Object destroyed.');
X
X getobj(n);
X obj.numexist := obj.numexist - 1;
X putobj;
X end;
X end else
X writeln('Such a thing is not here.');
X end else
X writeln('No such thing can be seen here.');
Xend;
X
X
Xfunction links_possible: boolean;
Xvar
X i: integer;
X
Xbegin
X gethere;
X links_possible := false;
X if is_owner(location,TRUE) then
X links_possible := true
X else begin
X for i := 1 to maxexit do
X if (here.exits[i].toloc = 0) and (here.exits[i].kind = 5) then
X links_possible := true;
X end;
Xend;
X
X
X
X{ make a room }
Xprocedure do_form(s: string);
X
Xbegin
X gethere;
X if checkhide then begin
X if links_possible then begin
X if s = '' then begin
X grab_line('Room name: ',s);
X end;
X s := slead(s);
X
X createroom(s);
X end else begin
X writeln('You may not create any new exits here. Go to a place where you can create');
X writeln('an exit before FORMing a new room.');
X end;
X end;
Xend;
X
X
Xprocedure xpoof; { loc: integer; forward }
Xvar
X targslot: integer;
X
Xbegin
X if put_token(loc,targslot,here.people[myslot].hiding) then begin
X if hiding then begin
X log_event(myslot,E_HPOOFOUT,0,0,myname,location);
X log_event(myslot,E_HPOOFIN,0,0,myname,loc);
X end else begin
X log_event(myslot,E_POOFOUT,0,0,myname,location);
X log_event(targslot,E_POOFIN,0,0,myname,loc);
X end;
X
X take_token(myslot,location);
X myslot := targslot;
X location := loc;
X setevent;
X do_look;
X end else
X writeln('There is a crackle of electricity, but the poof fails.');
Xend;
X
X
Xprocedure do_poof(s: string);
Xvar
X n,loc: integer;
X
Xbegin
X if privd then begin
X gethere;
X if lookup_room(loc,s) then begin
X xpoof(loc);
X end else if parse_pers(n,s) then begin
X grab_line('What room? ',s);
X if lookup_room(loc,s) then begin
X log_event(myslot,E_POOFYOU,n,loc);
X writeln;
X writeln('You extend your arms, muster some energy, and ',here.people[n].name,' is');
X writeln('engulfed in a cloud of orange smoke.');
X writeln;
X end else
X writeln('There is no room named ',s,'.');
X end else
X writeln('There is no room named ',s,'.');
X end else
X writeln('Only the Monster Manager may poof.');
Xend;
X
X
Xprocedure link_room(origdir,targdir,targroom: integer);
X
Xbegin
X { since exit creation involves the writing of two records,
X perhaps there should be a global lock around this code,
X such as a get to some obscure index field or something.
X I haven't put this in because I don't believe that if this
X routine fails it will seriously damage the database.
X
X Actually, the lock should be on the test (do_link) but that
X would be hard }
X
X getroom;
X with here.exits[origdir] do begin
X toloc := targroom;
X kind := 1; { type of exit, they can customize later }
X slot := targdir; { exit it comes out in in target room }
X
X init_exit(origdir);
X end;
X putroom;
X
X log_event(myslot,E_NEWEXIT,0,0,myname,location);
X if location <> targroom then
X log_event(0,E_NEWEXIT,0,0,myname,targroom);
X
X getroom(targroom);
X with here.exits[targdir] do begin
X toloc := location;
X kind := 1;
X slot := origdir;
X
X init_exit(targdir);
X end;
X putroom;
X writeln('Exit created. Use CUSTOM ',direct[origdir],' to customize your exit.');
Xend;
X
X
X{
XUser procedure to link a room
X}
Xprocedure do_link(s: string);
Xvar
X ok: boolean;
X orgexitnam,targnam,trgexitnam: string;
X targroom, { number of target room }
X targdir, { number of target exit direction }
X origdir: integer;{ number of exit direction here }
X firsttime: boolean;
X
Xbegin
X
X{ gethere; ! done in links_possible }
X
X if links_possible then begin
X log_action(link,0);
X if checkhide then begin
X writeln('Hit return alone at any prompt to terminate exit creation.');
X writeln;
X
X if s = '' then
X firsttime := false
X else begin
X orgexitnam := bite(s);
X firsttime := true;
X end;
X
X repeat
X if not(firsttime) then
X grab_line('Direction of exit? ',orgexitnam)
X else
X firsttime := false;
X
X ok :=lookup_dir(origdir,orgexitnam);
X if ok then
X ok := can_make(origdir);
X until (orgexitnam = '') or ok;
X
X if ok then begin
X if s = '' then
X firsttime := false
X else begin
X targnam := s;
X firsttime := true;
X end;
X
X repeat
X if not(firsttime) then
X grab_line('Room to link to? ',targnam)
X else
X firsttime := false;
X
X ok := lookup_room(targroom,targnam);
X until (targnam = '') or ok;
X end;
X
X if ok then begin
X repeat
X writeln('Exit comes out in target room');
X grab_line('from what direction? ',trgexitnam);
X ok := lookup_dir(targdir,trgexitnam);
X if ok then
X ok := can_make(targdir,targroom);
X until (trgexitnam='') or ok;
X end;
X
X if ok then begin { actually create the exit }
X link_room(origdir,targdir,targroom);
X end;
X end;
X end else
X writeln('No links are possible here.');
Xend;
X
X
Xprocedure relink_room(origdir,targdir,targroom: integer);
Xvar
X tmp: exit;
X copyslot,
X copyloc: integer;
X
Xbegin
X gethere;
X tmp := here.exits[origdir];
X copyloc := tmp.toloc;
X copyslot := tmp.slot;
X
X getroom(targroom);
X here.exits[targdir] := tmp;
X putroom;
X
X getroom(copyloc);
X here.exits[copyslot].toloc := targroom;
X here.exits[copyslot].slot := targdir;
X putroom;
X
X getroom;
X here.exits[origdir].toloc := 0;
X init_exit(origdir);
X putroom;
Xend;
X
X
Xprocedure do_relink(s: string);
Xvar
X ok: boolean;
X orgexitnam,targnam,trgexitnam: string;
X targroom, { number of target room }
X targdir, { number of target exit direction }
X origdir: integer;{ number of exit direction here }
X firsttime: boolean;
X
Xbegin
X log_action(c_relink,0);
X gethere;
X if checkhide then begin
X writeln('Hit return alone at any prompt to terminate exit relinking.');
X writeln;
X
X if s = '' then
X firsttime := false
X else begin
X orgexitnam := bite(s);
X firsttime := true;
X end;
X
X repeat
X if not(firsttime) then
X grab_line('Direction of exit to relink? ',orgexitnam)
X else
X firsttime := false;
X
X ok :=lookup_dir(origdir,orgexitnam);
X if ok then
X ok := can_alter(origdir);
X until (orgexitnam = '') or ok;
X
X if ok then begin
X if s = '' then
X firsttime := false
X else begin
X targnam := s;
X firsttime := true;
X end;
X
X repeat
X if not(firsttime) then
X grab_line('Room to relink exit into? ',targnam)
X else
X firsttime := false;
X
X ok := lookup_room(targroom,targnam);
X until (targnam = '') or ok;
X end;
X
X if ok then begin
X repeat
X writeln('New exit comes out in target room');
X grab_line('from what direction? ',trgexitnam);
X ok := lookup_dir(targdir,trgexitnam);
X if ok then
X ok := can_make(targdir,targroom);
X until (trgexitnam='') or ok;
X end;
X
X if ok then begin { actually create the exit }
X relink_room(origdir,targdir,targroom);
X end;
X end;
Xend;
X
X
X{ print the room default no-go message if there is one;
X otherwise supply the generic "you can't go that way" }
X
Xprocedure default_fail;
X
Xbegin
X if (here.exitfail <> 0) and (here.exitfail <> DEFAULT_LINE) then
X print_desc(here.exitfail)
X else
X writeln('You can''t go that way.');
Xend;
X
Xprocedure exit_fail(dir: integer);
Xvar
X tmp: string;
X
Xbegin
X if (dir < 1) or (dir > maxexit) then
X default_fail
X else if (here.exits[dir].fail = DEFAULT_LINE) then begin
X case here.exits[dir].kind of
X 5: writeln('There isn''t an exit there yet.');
X 6: writeln('You don''t have the power to go there.');
X otherwise default_fail;
X end;
X end else if here.exits[dir].fail <> 0 then
X block_subs(here.exits[dir].fail,myname);
X
X
X{ now print the exit failure message for everyone else in the room:
X if they tried to go through a valid exit,
X and the exit has an other-person failure desc, then
X substitute that one & use;
X
X if there is a room default other-person failure desc, then
X print that;
X
X if they tried to go through a valid exit,
X and the exit has no required alias, then
X print default exit fail
X else
X print generic "didn't leave room" message
X
Xcases:
X1) valid/alias exit and specific fail message
X2) valid/alias exit and blanket fail message
X3) valid exit (no specific or blanket) "x fails to go [direct]"
X4) alias exit and blanket fail
X5) blanket fail
X6) generic fail
X}
X
X if dir <> 0 then
X log_event(myslot,E_FAILGO,dir,0);
Xend;
X
X
X
Xprocedure do_exit; { (exit_slot: integer)-- declared forward }
Xvar
X orig_slot,
X targ_slot,
X orig_room,
X enter_slot,
X targ_room: integer;
X doalook: boolean;
X
Xbegin
X if (exit_slot < 1) or (exit_slot > 6) then
X exit_fail(exit_slot)
X else if here.exits[exit_slot].toloc > 0 then begin
X block_subs(here.exits[exit_slot].success,myname);
X
X orig_slot := myslot;
X orig_room := location;
X targ_room := here.exits[exit_slot].toloc;
X enter_slot := here.exits[exit_slot].slot;
X doalook := here.exits[exit_slot].autolook;
X
X { optimization for exit that goes nowhere;
X why go nowhere? For special effects, we
X don't want it to take too much time,
X the logs are important because they force the
X exit descriptions, but actually moving the
X player is unnecessary }
X
X if orig_room = targ_room then begin
X log_exit(exit_slot,orig_room,orig_slot);
X log_entry(enter_slot,targ_room,orig_slot);
X { orig_slot in log_entry 'cause we're not
X really going anwhere }
X if doalook then
X do_look;
X end else begin
X take_token(orig_slot,orig_room);
X if not put_token(targ_room,targ_slot) then begin
X { no room in room! }
X{ put them back! Quick! } if not put_token(orig_room,myslot) then begin
X writeln('%Oh no!');
X halt;
X end;
X end else begin
X log_exit(exit_slot,orig_room,orig_slot);
X log_entry(enter_slot,targ_room,targ_slot);
X
X myslot := targ_slot;
X location := targ_room;
X setevent;
X
X if doalook then
X do_look;
X end;
X end;
X end else
X exit_fail(exit_slot);
Xend;
X
X
X
Xfunction cycle_open: boolean;
Xvar
X ch: char;
X s: string;
X
Xbegin
X s := systime;
X ch := s[5];
X if ch in ['1','3','5','7','9'] then
X cycle_open := true
X else
X cycle_open := false;
Xend;
X
X
Xfunction which_dir(var dir:integer;s: string): boolean;
Xvar
X aliasdir, exitdir: integer;
X aliasmatch,exitmatch,
X aliasexact,exitexact: boolean;
X exitreq: boolean;
X
Xbegin
X s := lowcase(s);
X if lookup_alias(aliasdir,s) then
X aliasmatch := true
X else
X aliasmatch := false;
X if lookup_dir(exitdir,s) then
X exitmatch := true
X else
X exitmatch := false;
X if aliasmatch then begin
X if s = here.exits[aliasdir].alias then
X aliasexact := true
X else
X aliasexact := false;
X end else
X aliasexact := false;
X if exitmatch then begin
X if (s = direct[exitdir]) or (s = substr(direct[exitdir],1,1)) then
X exitexact := true
X else
X exitexact := false;
X end else
X exitexact := false;
X if exitmatch then
X exitreq := here.exits[exitdir].reqalias
X else
X exitreq := false;
X
X dir := 0;
X which_dir := true;
X if aliasexact and exitexact then
X dir := aliasdir
X else if aliasexact then
X dir := aliasdir
X else if exitexact and not exitreq then
X dir := exitdir
X else if aliasmatch then
X dir := aliasdir
X else if exitmatch and not exitreq then
X dir := exitdir
X else if exitmatch and exitreq then begin
X dir := exitdir;
X which_dir := false;
X end else begin
X which_dir := false;
X end;
Xend;
X
X
Xprocedure exit_case(dir: integer);
X
Xbegin
X case here.exits[dir].kind of
X 0: exit_fail(dir);
X 1: do_exit(dir); { more checking goes here }
X
X 3: if obj_hold(here.exits[dir].objreq) then
X exit_fail(dir)
X else
X do_exit(dir);
X 4: if rnd100 < 34 then
X do_exit(dir)
X else
X exit_fail(dir);
X
X 2: begin
X if obj_hold(here.exits[dir].objreq) then
X do_exit(dir)
X else
X exit_fail(dir);
X end;
X 6: if obj_hold(here.exits[dir].objreq) then
X do_exit(dir)
X else
X exit_fail(dir);
X 7: if cycle_open then
X do_exit(dir)
X else
X exit_fail(dir);
X end;
Xend;
X
X{
XPlayer wants to go to s
XHandle everthing, this is the top level procedure
X
XCheck that he can go to s
XPut him through the exit ( in do_exit )
XDo a look for him ( in do_exit )
X}
Xprocedure do_go(s: string;verb:boolean := true);
Xvar
X dir: integer;
X
Xbegin
X gethere;
X if checkhide then begin
X if length(s) = 0 then
X writeln('You must give the direction you wish to travel.')
X else begin
X if which_dir(dir,s) then begin
X if (dir >= 1) and (dir <= maxexit) then begin
X if here.exits[dir].toloc = 0 then begin
X exit_fail(dir);
X end else begin
X exit_case(dir);
X end;
X end else
X exit_fail(dir);
X end else
X exit_fail(dir);
X end;
X end;
Xend;
X
X
Xprocedure nice_say(var s: string);
X
Xbegin
X { capitalize the first letter of their sentence }
X
X if s[1] in ['a'..'z'] then
X s[1] := chr( ord('A') + (ord(s[1]) - ord('a')) );
X
X { put a period on the end of their sentence if
X they don't use any punctuation. }
X
X if s[length(s)] in ['a'..'z','A'..'Z'] then
X s := s + '.';
Xend;
X
X
Xprocedure do_say(s:string);
X
Xbegin
X if length(s) > 0 then begin
X
X{ if length(s) + length(myname) > 79 then begin
X s := substr(s,1,75-length(myname));
X writeln('Your message was truncated:');
X writeln('-- ',s);
X end; }
X
X nice_say(s);
X if hiding then
X log_event(myslot,E_HIDESAY,0,0,s)
X else
X log_event(myslot,E_SAY,0,0,s);
X end else
X writeln('To talk to others in the room, type SAY .');
Xend;
X
Xprocedure do_setname(s: string);
Xvar
X notice: string;
X ok: boolean;
X dummy: integer;
X sprime: string;
X
Xbegin
X gethere;
X if s <> '' then begin
X if length(s) <= shortlen then begin
X sprime := lowcase(s);
X if (sprime = 'monster manager') and (userid <> MM_userid) then begin
X writeln('Only the Monster Manager can have that personal name.');
X ok := false;
X end else if (sprime = 'vice manager') and (userid <> MVM_userid) then begin
X writeln('Only the Vice Manager can have that name.');
X ok := false;
X end else if (sprime = 'faust') and (userid <> FAUST_userid) then begin
X writeln('You are not Faust! You may not have that name.');
X ok := false;
X end else
X ok := true;
X
X if ok then
X if exact_pers(dummy,sprime) then begin
X if dummy = myslot then
X ok := true
X else begin
X writeln('Someone already has that name. Your personal name must be unique.');
X ok := false;
X end;
X end;
X
X if ok then begin
X myname := s;
X getroom;
X notice := here.people[myslot].name;
X here.people[myslot].name := s;
X putroom;
X notice := notice + ' is now known as ' + s;
X
X if not(hiding) then
X log_event(0,E_SETNAM,0,0,notice);
X { slot 0 means notify this player also }
X
X getpers; { note the new personal name in the logfile }
X pers.idents[mylog] := s; { don't lowcase it }
X putpers;
X end;
X end else
X writeln('Please limit your personal name to ',shortlen:1,' characters.');
X end else
X writeln('You are known to others as ',myname);
Xend;
X
Xfunction sysdate:string;
Xvar
X thedate: packed array[1..11] of char;
X
Xbegin
X date(thedate);
X sysdate := thedate;
Xend;
X
X
X{
X1234567890123456789012345678901234567890
Xexample display for alignment:
X
X Monster Status
X 19-MAR-1988 08:59pm
X
X}
X
Xprocedure do_who;
Xvar
X i,j: integer;
X ok: boolean;
X metaok: boolean;
X roomown: veryshortstring;
X
Xbegin
X log_event(myslot,E_WHO,0,(rnd100 mod 4));
X
X { we need just about everything to print this list:
X player alloc index, userids, personal names,
X room names, room owners, and the log record }
X
X getindex(I_ASLEEP); { Get index of people who are playing now }
X freeindex;
X getuser;
X freeuser;
X getpers;
X freepers;
X getnam;
X freenam;
X getown;
X freeown;
X getint(N_LOCATION); { get where they are }
X freeint;
X writeln(' Monster Status');
X writeln(' ',sysdate,' ',systime);
X writeln;
X writeln('Username Game Name Where');
X
X if (privd) { or has_kind(O_ALLSEEING) } then
X metaok := true
X else
X metaok := false;
X
X for i := 1 to indx.top do begin
X if not(indx.free[i]) then begin
X write(user.idents[i]);
X j := length(user.idents[i]);
X while j < 16 do begin
X write(' ');
X j := j + 1;
X end;
X
X write(pers.idents[i]);
X j := length(pers.idents[i]);
X while j <= 25 do begin
X write(' ');
X j := j + 1;
X end;
X
X if not(metaok) then begin
X roomown := own.idents[anint.int[i]];
X
X{ if a person is in a public or disowned room, or
X if they are in the domain of the WHOer, then the player should know
X where they are }
X
X if (roomown = '') or (roomown = '*') or
X (roomown = userid) then
X ok := true
X else
X ok := false;
X
X
X{ the player obviously knows where he is }
X if i = mylog then
X ok := true;
X end;
X
X
X if ok or metaok then begin
X writeln(nam.idents[anint.int[i]]);
X end else
X writeln('n/a');
X end;
X end;
Xend;
X
Xfunction own_trans(s: string): string;
X
Xbegin
X if s = '' then
X own_trans := ''
X else if s = '*' then
X own_trans := ''
X else
X own_trans := s;
Xend;
X
X
Xprocedure list_rooms(s: shortstring);
Xvar
X first: boolean;
X i,j,posit: integer;
X
Xbegin
X first := true;
X posit := 0;
X for i := 1 to indx.top do begin
X if (not indx.free[i]) and (own.idents[i] = s) then begin
X if posit = 3 then begin
X posit := 1;
X writeln;
X end else
X posit := posit + 1;
X if first then begin
X first := false;
X writeln(own_trans(s),':');
X end;
X write(' ',nam.idents[i]);
X for j := length(nam.idents[i]) to 21 do
X write(' ');
X end;
X end;
X if posit <> 3 then
X writeln;
X if first then
X writeln('No rooms owned by ',own_trans(s))
X else
X writeln;
Xend;
X
X
Xprocedure list_all_rooms;
Xvar
X i,j: integer;
X tmp: packed array[1..maxroom] of boolean;
X
Xbegin
X tmp := zero;
X list_rooms(''); { public rooms first }
X list_rooms('*'); { disowned rooms next }
X for i := 1 to indx.top do begin
X if not(indx.free[i]) and not(tmp[i]) and
X (own.idents[i] <> '') and (own.idents[i] <> '*') then begin
X list_rooms(own.idents[i]); { player rooms }
X for j := 1 to indx.top do
X if own.idents[j] = own.idents[i] then
X tmp[j] := TRUE;
X end;
X end;
Xend;
X
Xprocedure do_rooms(s: string);
Xvar
X cmd: string;
X id: veryshortstring;
X listall: boolean;
X
Xbegin
X getnam;
X freenam;
X getown;
X freeown;
X getindex(I_ROOM);
X freeindex;
X
X listall := false;
X s := lowcase(s);
X cmd := bite(s);
X if cmd = '' then
X id := userid
X else if cmd = 'public' then
X id := ''
X else if cmd = 'disowned' then
X id := '*'
X else if cmd = '' then
X id := ''
X else if cmd = '' then
X id := '*'
X else if cmd = '*' then
X listall := true
X else if length(cmd) > veryshortlen then
X id := substr(cmd,1,veryshortlen)
X else
X id := cmd;
X
X if listall then begin
X if privd then
X list_all_rooms
X else
X writeln('You may not obtain a list of all the rooms.');
X end else begin
X if privd or (userid = id) or (id = '') or (id = '*') then
X list_rooms(id)
X else
X writeln('You may not list rooms that belong to another player.');
X end;
Xend;
X
X
X
Xprocedure do_objects;
Xvar
X i: integer;
X total,public,disowned,private: integer;
X
Xbegin
X getobjnam;
X freeobjnam;
X getobjown;
X freeobjown;
X getindex(I_OBJECT);
X freeindex;
X
X total := 0;
X public := 0;
X disowned := 0;
X private := 0;
X
X writeln;
X for i := 1 to indx.top do begin
X if not(indx.free[i]) then begin
X total := total + 1;
X if objown.idents[i]='' then begin
X writeln(i:4,' ','':12,' ',objnam.idents[i]);
X public := public + 1
X end else if objown.idents[i]='*' then begin
X writeln(i:4,' ','':12,' ',objnam.idents[i]);
X disowned := disowned + 1
X end else begin
X private := private + 1;
X
X if (objown.idents[i] = userid) or
X (privd) then begin
X{ >>>>>> } writeln(i:4,' ',objown.idents[i]:12,' ',objnam.idents[i]);
X end;
X end;
X end;
X end;
X writeln;
X writeln('Public: ',public:4);
X writeln('Disowned: ',disowned:4);
X writeln('Private: ',private:4);
X writeln(' ----');
X writeln('Total: ',total:4);
Xend;
X
X
Xprocedure do_claim(s: string);
Xvar
X n: integer;
X ok: boolean;
X tmp: string;
X
Xbegin
X if length(s) = 0 then begin { claim this room }
X getroom;
X if (here.owner = '*') or (privd) then begin
X here.owner := userid;
X putroom;
X getown;
X own.idents[location] := userid;
X putown;
X log_event(myslot,E_CLAIM,0,0);
X writeln('You are now the owner of this room.');
X end else begin
X freeroom;
X if here.owner = '' then
X writeln('This is a public room. You may not claim it.')
X else
X writeln('This room has an owner.');
X end;
X end else if lookup_obj(n,s) then begin
X getobjown;
X freeobjown;
X if objown.idents[n] = '' then
X writeln('That is a public object. You may DUPLICATE it, but may not CLAIM it.')
X else if objown.idents[n] <> '*' then
X writeln('That object has an owner.')
X else begin
X getobj(n);
X freeobj;
X if obj.numexist = 0 then
X ok := true
X else begin
X if obj_hold(n) or obj_here(n) then
X ok := true
X else
X ok := false;
X end;
X
X if ok then begin
X getobjown;
X objown.idents[n] := userid;
X putobjown;
X tmp := obj.oname;
X log_event(myslot,E_OBJCLAIM,0,0,tmp);
X writeln('You are now the owner the ',tmp,'.');
X end else
X writeln('You must have one to claim it.');
X end;
X end else
X writeln('There is nothing here by that name to claim.');
Xend;
X
Xprocedure do_disown(s: string);
Xvar
X n: integer;
X tmp: string;
X
Xbegin
X if length(s) = 0 then begin { claim this room }
X getroom;
X if (here.owner = userid) or (privd) then begin
X getroom;
X here.owner := '*';
X putroom;
X getown;
X own.idents[location] := '*';
X putown;
X log_event(myslot,E_DISOWN,0,0);
X writeln('You have disowned this room.');
X end else begin
X freeroom;
X writeln('You are not the owner of this room.');
X end;
X end else begin { disown an object }
X if lookup_obj(n,s) then begin
X getobj(n);
X freeobj;
X tmp := obj.oname;
X
X getobjown;
X if objown.idents[n] = userid then begin
X objown.idents[n] := '*';
X putobjown;
X log_event(myslot,E_OBJDISOWN,0,0,tmp);
X writeln('You are no longer the owner of the ',tmp,'.');
X end else begin
X freeobjown;
X writeln('You are not the owner of any such thing.');
X end;
X end else
X writeln('You are not the owner of any such thing.');
X end;
Xend;
X
X
Xprocedure do_public(s: string);
Xvar
X ok: boolean;
X tmp: string;
X n: integer;
X
Xbegin
X if privd then begin
X if length(s) = 0 then begin
X getroom;
X here.owner := '';
X putroom;
X getown;
X own.idents[location] := '';
X putown;
X end else if lookup_obj(n,s) then begin
X getobjown;
X freeobjown;
X if objown.idents[n] = '' then
X writeln('That is already public.')
X else begin
X getobj(n);
X freeobj;
X if obj.numexist = 0 then
X ok := true
X else begin
X if obj_hold(n) or obj_here(n) then
X ok := true
X else
X ok := false;
X end;
X
X if ok then begin
X getobjown;
X objown.idents[n] := '';
X putobjown;
X
X tmp := obj.oname;
X log_event(myslot,E_OBJPUBLIC,0,0,tmp);
X writeln('The ',tmp,' is now public.');
X end else
X writeln('You must have one to claim it.');
X end;
X end else
X writeln('There is nothing here by that name to claim.');
X end else
X writeln('Only the Monster Manager may make things public.');
Xend;
X
X
X
X{ sum up the number of real exits in this room }
X
Xfunction find_numexits: integer;
Xvar
X i: integer;
X sum: integer;
X
Xbegin
X sum := 0;
X for i := 1 to maxexit do
X if here.exits[i].toloc <> 0 then
X sum := sum + 1;
X find_numexits := sum;
Xend;
X
X
X
X{ clear all people who have played monster and quit in this location
X out of the room so that when they start up again they won't be here,
X because we are destroying this room }
X
Xprocedure clear_people(loc: integer);
Xvar
X i: integer;
X
Xbegin
X getint(N_LOCATION);
X for i := 1 to maxplayers do
X if anint.int[i] = loc then
X anint.int[i] := 1;
X putint;
Xend;
X
X
Xprocedure do_zap(s: string);
Xvar
X loc: integer;
X
Xbegin
X gethere;
X if checkhide then begin
X if lookup_room(loc,s) then begin
X gethere(loc);
X if (here.owner = userid) or (privd) then begin
X clear_people(loc);
X if find_numpeople = 0 then begin
X if find_numexits = 0 then begin
X if find_numobjs = 0 then begin
X del_room(loc);
X writeln('Room deleted.');
X end else
X writeln('You must remove all of the objects from that room first.');
X end else
X writeln('You must delete all of the exits from that room first.');
X end else
X writeln('Sorry, you cannot destroy a room if people are still in it.');
X end else
X writeln('You are not the owner of that room.');
X end else
X writeln('There is no room named ',s,'.');
X end;
Xend;
X
X
Xfunction room_nameinuse(num: integer; newname: string): boolean;
Xvar
X dummy: integer;
X
Xbegin
X if exact_obj(dummy,newname) then begin
X if dummy = num then
X room_nameinuse := false
X else
X room_nameinuse := true;
X end else
X room_nameinuse := false;
Xend;
X
X
X
Xprocedure do_rename;
Xvar
X dummy: integer;
X newname: string;
X s: string;
X
Xbegin
X gethere;
X writeln('This room is named ',here.nicename);
X writeln;
X grab_line('New name: ',newname);
X if (newname = '') or (newname = '**') then
X writeln('No changes.')
X else if length(newname) > shortlen then
X writeln('Please limit your room name to ',shortlen:1,' characters.')
X else if room_nameinuse(location,newname) then
X writeln(newname,' is not a unique room name.')
X else begin
X getroom;
X here.nicename := newname;
X putroom;
X
X getnam;
X nam.idents[location] := lowcase(newname);
X putnam;
X writeln('Room name updated.');
X end;
Xend;
X
X
Xfunction obj_nameinuse(objnum: integer; newname: string): boolean;
Xvar
X dummy: integer;
X
Xbegin
X if exact_obj(dummy,newname) then begin
X if dummy = objnum then
X obj_nameinuse := false
X else
X obj_nameinuse := true;
X end else
X obj_nameinuse := false;
Xend;
X
X
Xprocedure do_objrename(objnum: integer);
Xvar
X newname: string;
X s: string;
X
Xbegin
X getobj(objnum);
X freeobj;
X
X writeln('This object is named ',obj.oname);
X writeln;
X grab_line('New name: ',newname);
X if (newname = '') or (newname = '**') then
X writeln('No changes.')
X else if length(newname) > shortlen then
X writeln('Please limit your object name to ',shortlen:1,' characters.')
X else if obj_nameinuse(objnum,newname) then
X writeln(newname,' is not a unique object name.')
X else begin
X getobj(objnum);
X obj.oname := newname;
X putobj;
X
X getobjnam;
X objnam.idents[objnum] := lowcase(newname);
X putobjnam;
X writeln('Object name updated.');
X end;
Xend;
X
X
X
Xprocedure view_room;
Xvar
X s: string;
X i: integer;
X
Xbegin
X writeln;
X getnam;
X freenam;
X getobjnam;
X freeobjnam;
X
X with here do begin
X writeln('Room: ',nicename);
X case nameprint of
X 0: writeln('Room name not printed');
X 1: writeln('"You''re in" precedes room name');
X 2: writeln('"You''re at" precedes room name');
X otherwise writeln('Room name printing is damaged.');
X end;
X
X write('Room owner: ');
X if owner = '' then
X writeln('')
X else if owner = '*' then
X writeln('')
X else
X writeln(owner);
X
X if primary = 0 then
X writeln('There is no primary description')
X else
X writeln('There is a primary description');
X
X if secondary = 0 then
X writeln('There is no secondary description')
X else
X writeln('There is a secondary description');
X
X case which of
X 0: writeln('Only the primary description will print');
X 1: writeln('Only the secondary description will print');
X 2: writeln('Both the primary and secondary descriptions will print');
X 3: begin
X writeln('The primary description will print, followed by the seconary description');
X writeln('if the player is holding the magic object');
X end;
X 4: begin
X writeln('If the player is holding the magic object, the secondary description will print');
X writeln('Otherwise, the primary description will print');
X end;
X otherwise writeln('The way the room description prints is damaged');
X end;
X
X writeln;
X if magicobj = 0 then
X writeln('There is no magic object for this room')
X else
X writeln('The magic object for this room is the ',objnam.idents[magicobj],'.');
X
X if objdrop = 0 then
X writeln('Dropped objects remain here')
X else begin
X writeln('Dropped objects go to ',nam.idents[objdrop],'.');
X if objdesc = 0 then
X writeln('Dropped.')
X else
X print_line(objdesc);
X if objdest = 0 then
X writeln('Nothing is printed when object "bounces in" to target room')
X else
X print_line(objdest);
X end;
X writeln;
X if trapto = 0 then
X writeln('There is no trapdoor set')
X else
X writeln('The trapdoor sends players ',direct[trapto],
X ' with a chance factor of ',trapchance:1,'%');
X
X for i := 1 to maxdetail do begin
X if length(detail[i]) > 0 then begin
X write('Detail "',detail[i],'" ');
X if detaildesc[i] > 0 then
X writeln('has a description')
X else
X writeln('has no description');
X end;
X end;
X writeln;
X end;
Xend;
X
X
Xprocedure room_help;
X
Xbegin
X writeln;
X writeln('D Alter the way the room description prints');
X writeln('N Change how the room Name prints');
X writeln('P Edit the Primary room description [the default one] (same as desc)');
X writeln('S Edit the Secondary room description');
X writeln('X Define a mystery message');
X writeln;
X writeln('G Set the location that a dropped object really Goes to');
X writeln('O Edit the object drop description (for drop effects)');
X writeln('B Edit the target room (G) "bounced in" description');
X writeln;
X writeln('T Set the direction that the Trapdoor goes to');
X writeln('C Set the Chance of the trapdoor functioning');
X writeln;
X writeln('M Define the magic object for this room');
X writeln('R Rename the room');
X writeln;
X writeln('V View settings on this room');
X writeln('E Exit (same as quit)');
X writeln('Q Quit (same as exit)');
X writeln('? This list');
X writeln;
Xend;
X
X
X
Xprocedure custom_room;
Xvar
X done: boolean;
X prompt: string;
X n: integer;
X s: string;
X newdsc: integer;
X bool: boolean;
X
Xbegin
X log_action(e_custroom,0);
X writeln;
X writeln('Customizing this room');
X writeln('If you would rather be customizing an exit, type CUSTOM ');
X writeln('If you would rather be customizing an object, type CUSTOM ');
X writeln;
X done := false;
X prompt := 'Custom> ';
X
X repeat
X repeat
X grab_line(prompt,s);
X s := slead(s);
X until length(s) > 0;
X s := lowcase(s);
X case s[1] of
X
X 'e','q': done := true;
X '?','h': room_help;
X 'r': do_rename;
X 'v': view_room;
X{dir trapdoor goes} 't': begin
X grab_line('What direction does the trapdoor exit through? ',s);
X if length(s) > 0 then begin
X if lookup_dir(n,s) then begin
X getroom;
X here.trapto := n;
X putroom;
X writeln('Room updated.');
X end else
X writeln('No such direction.');
X end else
X writeln('No changes.');
X end;
X{chance} 'c': begin
X writeln('Enter the chance that in any given minute the player will fall through');
X writeln('the trapdoor (0-100) :');
X writeln;
X grab_line('? ',s);
X if isnum(s) then begin
X n := number(s);
X if n in [0..100] then begin
X getroom;
X here.trapchance := n;
X putroom;
X end else
X writeln('Out of range.');
X end else
X writeln('No changes.');
X end;
X 's': begin
X newdsc := here.secondary;
X writeln('[ Editing the secondary room description ]');
X if edit_desc(newdsc) then begin
X getroom;
X here.secondary := newdsc;
X putroom;
X end;
X end;
X 'p': begin
X{ same as desc } newdsc := here.primary;
X writeln('[ Editing the primary room description ]');
X if edit_desc(newdsc) then begin
X getroom;
X here.primary := newdsc;
X putroom;
X end;
X end;
X 'o': begin
X writeln('Enter the line that will be printed when someone drops an object here:');
X writeln('If dropped objects do not stay here, you may use a # for the object name.');
X writeln('Right now it says:');
X if here.objdesc = 0 then
X writeln('Dropped. [default]')
X else
X print_line(here.objdesc);
X
X n := here.objdesc;
X make_line(n);
X getroom;
X here.objdesc := n;
X putroom;
X end;
X 'x': begin
X writeln('Enter a line that will be randomly shown.');
X writeln('Right now it says:');
X if here.objdesc = 0 then
X writeln('[none defined]')
X else
X print_line(here.rndmsg);
X
X n := here.rndmsg;
X make_line(n);
X getroom;
X here.rndmsg := n;
X putroom;
X end;
X{bounced in desc} 'b': begin
X writeln('Enter the line that will be displayed in the room where an object really');
X writeln('goes when an object dropped here "bounces" there:');
X writeln('Place a # where the object name should go.');
X writeln;
X writeln('Right now it says:');
X if here.objdest = 0 then
X writeln('Something has bounced into the room.')
X else
X print_line(here.objdest);
X
X n := here.objdest;
X make_line(n);
X getroom;
X here.objdest := n;
X putroom;
X end;
X 'm': begin
X getobjnam;
X freeobjnam;
X if here.magicobj = 0 then
X writeln('There is currently no magic object for this room.')
X else
X writeln(objnam.idents[here.magicobj],
X ' is currently the magic object for this room.');
X writeln;
X grab_line('New magic object? ',s);
X if s = '' then
X writeln('No changes.')
X else if lookup_obj(n,s) then begin
X getroom;
X here.magicobj := n;
X putroom;
X writeln('Room updated.');
X end else
X writeln('No such object found.');
X end;
X 'g': begin
X getnam;
X freenam;
X if here.objdrop = 0 then
X writeln('Objects dropped fall here.')
X else
X writeln('Objects dropped fall in ',nam.idents[here.objdrop],'.');
X writeln;
X writeln('Enter * for [this room]:');
X grab_line('Room dropped objects go to? ',s);
X if s = '' then
X writeln('No changes.')
X else if s = '*' then begin
X getroom;
X here.objdrop := 0;
X putroom;
X writeln('Room updated.');
X end else if lookup_room(n,s) then begin
X getroom;
X here.objdrop := n;
X putroom;
X writeln('Room updated.');
X end else
X writeln('No such room found.');
X end;
X 'd': begin
X writeln('Print room descriptions how?');
X writeln;
X writeln('0) Print primary (main) description only [default]');
X writeln('1) Print only secondary description.');
X writeln('2) Print both primary and secondary descriptions togther.');
X writeln('3) Print primary description first; then print secondary description only if');
X writeln(' the player is holding the magic object for this room.');
X writeln('4) Print secondary if holding the magic obj; print primary otherwise');
X writeln;
X grab_line('? ',s);
X if isnum(s) then begin
X n := number(s);
X if n in [0..4] then begin
X getroom;
X here.which := n;
X putroom;
X writeln('Room updated.');
X end else
X writeln('Out of range.');
X end else
X writeln('No changes.');
X
X end;
X 'n': begin
X writeln('How would you like the room name to print?');
X writeln;
X writeln('0) No room name is shown');
X writeln('1) "You''re in ..."');
X writeln('2) "You''re at ..."');
X writeln;
X grab_line('? ',s);
X if isnum(s) then begin
X n := number(s);
X if n in [0..2] then begin
X getroom;
X here.nameprint := n;
X putroom;
X end else
X writeln('Out of range.');
X end else
X writeln('No changes.');
X end;
X otherwise writeln('Bad command, type ? for a list');
X end;
X until done;
X log_event(myslot,E_ROOMDONE,0,0);
Xend;
X
Xprocedure analyze_exit(dir: integer);
Xvar
X s: string;
X
Xbegin
X writeln;
X getnam;
X freenam;
X getobjnam;
X freeobjnam;
X with here.exits[dir] do begin
X s := alias;
X if s = '' then
X s := '(no alias)'
X else
X s := '(alias ' + s + ')';
X if here.exits[dir].reqalias then
X s := s + ' (required)'
X else
X s := s + ' (not required)';
X
X if toloc <> 0 then
X writeln('The ',direct[dir],' exit ',s,' goes to ',nam.idents[toloc])
X else
X writeln('The ',direct[dir],' exit goes nowhere.');
X if hidden <> 0 then
X writeln('Concealed.');
X write('Exit type: ');
X case kind of
X 0: writeln('no exit.');
X 1: writeln('Open passage.');
X 2: writeln('Door, object required to pass.');
X 3: writeln('No passage if holding object.');
X 4: writeln('Randomly fails');
X 5: writeln('Potential exit.');
X 6: writeln('Only exists while holding the required object.');
X 7: writeln('Timed exit');
X end;
X if objreq = 0 then
X writeln('No required object.')
X else
X writeln('Required object is: ',objnam.idents[objreq]);
X
X
X writeln;
X if exitdesc = DEFAULT_LINE then
X exit_default(dir,kind)
X else
X print_line(exitdesc);
X
X if success = 0 then
X writeln('(no success message)')
X else
X print_desc(success);
X
X if fail = DEFAULT_LINE then begin
X if kind = 5 then
X writeln('There isn'' an exit there yet.')
X else
X writeln('You can''t go that way.');
X end else
X print_desc(fail);
X
X if comeout = DEFAULT_LINE then
X writeln('# has come into the room from: ',direct[dir])
X else
X print_desc(comeout);
X if goin = DEFAULT_LINE then
X writeln('# has gone ',direct[dir])
X else
X print_desc(goin);
X
X writeln;
X if autolook then
X writeln('LOOK automatically done after exit used')
X else
X writeln('LOOK supressed on exit use');
X if reqverb then
X writeln('The alias is required to be a verb for exit use')
X else
X writeln('The exit can be used with GO or as a verb');
X end;
X writeln;
Xend;
X
Xprocedure custom_help;
X
Xbegin
X writeln;
X writeln('A Set an Alias for the exit');
X writeln('C Conceal an exit');
X writeln('D Edit the exit''s main Description');
X writeln('E EXIT custom (saves changes)');
X writeln('F Edit the exit''s failure line');
X writeln('I Edit the line that others see when a player goes Into an exit');
X writeln('K Set the object that is the Key to this exit');
X writeln('L Automatically look [default] / don''t look on exit');
X writeln('O Edit the line that people see when a player comes Out of an exit');
X writeln('Q QUIT Custom (saves changes)');
X writeln('R Require/don''t require alias for exit; ignore direction');
X writeln('S Edit the success line');
X writeln('T Alter Type of exit (passage, door, etc)');
X writeln('V View exit information');
X writeln('X Require/don''t require exit name to be a verb');
X writeln('? This list');
X writeln;
Xend;
X
X
Xprocedure get_key(dir: integer);
Xvar
X s: string;
X n: integer;
X
Xbegin
X getobjnam;
X freeobjnam;
X if here.exits[dir].objreq = 0 then
X writeln('Currently there is no key set for this exit.')
X else
X writeln(objnam.idents[here.exits[dir].objreq],' is the current key for this exit.');
X writeln('Enter * for [no key]');
X writeln;
X
X grab_line('What object is the door key? ',s);
X if length(s) > 0 then begin
X if s = '*' then begin
X getroom;
X here.exits[dir].objreq := 0;
X putroom;
X writeln('Exit updated.');
X end else if lookup_obj(n,s) then begin
X getroom;
X here.exits[dir].objreq := n;
X putroom;
X writeln('Exit updated.');
X end else
X writeln('There is no object by that name.');
X end else
X writeln('No changes.');
Xend;
X
END_OF_FILE
if test 54281 -ne `wc -c <'mon3.pas'`; then
echo shar: \"'mon3.pas'\" unpacked with wrong size!
fi
# end of 'mon3.pas'
fi
if test -f 'privusers.pas' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'privusers.pas'\"
else
echo shar: Extracting \"'privusers.pas'\" \(880 characters\)
sed "s/^X//" >'privusers.pas' <<'END_OF_FILE'
X{ These are PRIVILEDGED users. The Monster Manager has the most power;
X this should be the game administrator. The Monster Vice Manager can help
X the MM in his adminstrative duties. Faust is another person who can do
X anything but is generally incognito. }
X
XMM_userid = 'dolpher'; { Monster Manager }
XMVM_userid = 'gary'; { Monster Vice Manager }
XFAUST_userid = 'skrenta'; { Dr. Faustus }
X
XREBUILD_OK = TRUE; { if this is TRUE, the MM can blow away
X and reformat the entire universe. It's
X a good idea to set this to FALSE and
X recompile after you've got your world
X going }
X
X
Xroot = 'USERC:[ISP00475.CRA01453.DSYS]';
X { this is where the Monster database goes
X This directory and the datafiles Monster
X creates in it must be world:rw for
X people to be able to play. This sucks,
X but we don't have setgid to games on VMS }
END_OF_FILE
if test 880 -ne `wc -c <'privusers.pas'`; then
echo shar: \"'privusers.pas'\" unpacked with wrong size!
fi
# end of 'privusers.pas'
fi
echo shar: End of archive 5 \(of 6\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 6 archives.
rm -f ark[1-9]isdone
./fixup.sh
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0