/***** Tool to make maps of domains, created by Hippo@Star Rift / Hippo@Heaven7 (dido.fa.indiana.edu 6666 / salvation.com 7777) Maps symbols: x : room S : room where you started mapping -|/\X : general exits E : other kind of exit other : special room (see SYMBOL_ROOM) ******/ #include <mudlib.h> #include "/include/fn/linewrap.h" inherit "/inherit/treasure.c"; #define VER "1.2.1" #define LOGFILE "done_map.log" #define HERE file_name(environment(this_object())) #define EX HERE->query_exits() #define MA member_array #define EXIT ({"north","northeast","east","southeast","south","southwest","west","northwest"}) #define SYMBOL ({ "|","/","-","\\","|","/","-","\\","E" }) #define PX ({ 0, 2, 2, 2, 0, -2, -2, -2, 0 }) #define PY ({ -2, -2, 0, 2, 2, 2, 0, -2, 0 }) #define SOMEROOM ({"shop","pub","post","guild","hall","street"}) #define SYMBOL_ROOM ({"s", "p", "P", "g", "h" ,"r" }) mixed *files,*xy; string map; int tot,maxx,maxy; void reset(status arg) { if(arg) return; set_name("tracker (Version "+VER+")"); set_id("tracker"); set_short("Tracker (Version "+VER+")"); set_long("\n"+ " .------------------. \n"+ " /' T R A C K E R /| \n"+ " /' a tool to help /' | \n"+ " /' you making maps /' /' \n"+ " |~~~~~~~~~~~~~~~~~~~| /' \n"+ " |___________________|/' \n"+ " `|:. `|. |' :|' \n"+ " `:|:.`|.| :|' \n"+ " `:|`||:|' \n"+ " ``X' \n"+ " ====T==== \n"+ " || ||# || \n"+ " _## ##~ ##_ \n"+ " ~~ \n"+ " <'help tracker' for more info> \n"); } drop() { return 0; } get() { return 0; } void init() { ::init(); add_action("start_map","track"); add_action("bugs","bugs"); add_action("show_files","files"); add_action("show_map","showmap"); add_action("ver","ver"); add_action("help","help"); } status ver(string str) { if(str=="tracker") { write ("\nVersion\tEditor\tDate\tDescription\n"+ "~~~~~~~\t~~~~~~\t~~~~ \t~~~~~~~~~~~\n"+ "1.0.0\tHippo\t06-02-95\tCreation of the tool\n"+ "1.1.0\tHippo\t06-14-95\tMajor debugging finished\n"+ "1.1.1\tHippo\t06-20-95\tAdded useful error messages\n"+ "1.2.1\tHippo\t08-22-95\tAdded symbols for specific rooms\n"+ ""); return 1; } return 0; } status help(string str) { if(str=="tracker") { write("\n"+ "**************************************************************************\n"+ " Tool to make maps of domains (Version "+VER+")\n"+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"+ " maps symbols\n"+ " x : room\n"+ " S : the room where the tracker started (change later manually to x)\n"+ " E : room with an irregular exit\n"+ " -|/\\X : doorways\n"+ " other : symbols for specific rooms, explained at the map itselfn"+ "\n"+ " possible commands\n"+ " track : start map-making of the realm where Tracker is now\n"+ " files : shows the filenames and the exit-codes for debugging\n"+ " showmap : shows the map Tracker just created \n"+ " (also written in /players/"+this_player()->query_real_name()+"/"+LOGFILE+")\n"+ " help tracker : this info\n"+ " bugs tracker : what to do in case of new ideas, bugs or problems?\n"+ " ver tracker : information on the creation and updating of Tracker\n"+ "**************************************************************************\n"); return 1; } return 0; } status bugs(string str) { /*** if(str=="tracker") { writelw("If you discover a problem of any kind while using the tracker, "+ "please mail the one who created this version (<ver tracker>) "+ "about it. Include a description in that mail of what "+ "exactly happened (or didn't happen) and where (realm and room) it "+ "occured. If you have a clue to the "+ "problem that caused the error, or if you debugged the Tracker "+ "yourself already, include that information, too! I'll try to fix it, "+ "or reply, telling what went wrong, as soon as possible.\n"+ "Finally, if you have any kind of "+ "comment on this tool, I'd like to hear it from you. Also "+ "suggestions to upgrade the Tracker, or extending its "+ "possibilities are very welcome and will be considered. "+ "\n\nHippo\n"); return 1; } */ return 0; } /**************************************************** * For debugging purposes: show_files() and show_map * ****************************************************/ status convert_xy2map() { int x,y; for(y=0;y<=maxy;y++) { for(x=0;x<=maxx;x++) { map=map+(((string)xy[x][y]==0 || (string)xy[x][y]=="") ? " " : (string)xy[x][y]); } map+="\n"; } map+="\n"; if(maxx>75) { map=lw("WARNING: "+ "The map might seem a bit messed up, because it exceeds 75 chars "+ "horizontally. The easiest way to solve this problem is to split "+ "it into 2 parts manually.\n"); } return 1; } status show_files() { int i; string s; write("\n n . e . s . w . E\n"); for(i=0;i<=tot;i+=2) { s=files[i]+" "; write(extract(s,0,50)+files[i+1]+"\n"); } return 1; } status show_map() { if(map==0 || map=="") convert_xy2map(); if(map==0 || map=="") writelw("You didn't create a map, as far as I know. "+ "Type 'help tracker' for more information."); else write(map+"\n"); return 1; } /***************************************************** * make sure the trackers destruct themselves finally * *****************************************************/ void destmap(int tel) { if(tel==0) { writelw("You can find yourself a new Tracker in "+ file_name(this_object())+"!!\n"); write("Tracker has been destructed.\n"); destruct(this_object()); } else { writelw("Tracker will destruct in "+(string)(tel*40)+ " seconds if you don't command Tracker to track a new map.\n"); tel--; call_out("destmap",40,tel); } } /*********************************************************** * The realm is bugged => bring tracker back to the wizard. * ***********************************************************/ string bugged_room(int this) { int bugged,i,j; string *tmp; i=1; bugged=0; while(bugged<=tot-this) { tmp=explode((string)files[this-i]," "); for(j=0;j<sizeof(tmp);j++) if(tmp[j]=="1") bugged+=2; i+=2; } return files[this-i+1]; } status bugged_realm(int this) { writelw("The tracker tells you: It seems to me that "+files[this]+ ((file_size(files[this]+".c") > 1) ? " is bugged." : " doesn't exist.")+ " Obviously, an exit from room "+bugged_room(this)+ " refers to that place. Therefore, I can't finish the map now."+ " If you still want to make the map, and the bug cannot be"+ " fixed at this moment, change the concerning exit in"+ " that room into an exitname other than one of "+ implode(EXIT," ")+" and track the realm again.\n"); move_object(this_object(),environment(this_player())); call_out("destmap",0,5); // make sure the tracker destructs! return 1; } /************************************************* * Check all rooms for exits (doors are included) * **************************************************/ status too_long_message() { //this error can't be fixed in a proper way! /* writelw("This realm seems quite large. It's possible that "+ "the tracker will quit with the error message "+ "<too long evaluation>. There are three possible methods to "+ "handle this.\n"+ "1. Ask your admin to increase the number "+ "of loops that are allowed to pass by a program.\n"+ "2. Try to decrease the size of the realm by changing a "+ "crucial exit somewhere, create the maps of both parts "+ "seperately and manually make one map of them.\n"+ "3. Change this file in a way that it creates a temporary "+ "file on the disk and add a <continue> command. I'll probably "+ "do this myself when I have more time.\n"); */ return 1; } string convert2fil(string str) { string s; if(sscanf(str,"%s.c",s)==1) str=s; if(extract(str,0,0)=="/") str=extract(str,1); return str; } int is_exit(string str) { if(MA(str,EX)!=-1) { if(MA(convert2fil(EX[MA(str,EX)-1]),files)==-1) { tot+=2; files[tot]=convert2fil(EX[MA(str,EX)-1]); return 1; } else { return ((convert2fil(EX[MA(str,EX)-1])==HERE) ? 0 : 2); } } return 0; } status extra_ex() { int j; for(j=1;j<sizeof(EX);j+=2) if(MA(EX[j],EXIT)==-1) return 1; return 0; } status make_file_string() { int i,this; status mess; tot=0; this=0; mess=0; files[this]=HERE; while(tot>=this && files[this]!="") { this++; for(i=0;i<sizeof(EXIT);i++) files[this]+=(string)is_exit(EXIT[i])+" "; files[this]+=(string)extra_ex()+" "; this++; call_out("bugged_realm",2,this); /* if files[this] is bugged, program will quit at next line */ if(files[this]!="") move_object(this_object(),files[this]); remove_call_out("bugged_realm"); // if files[this] was not bugged if(tot>10 && !mess) { too_long_message(); mess=1; } } writelw("There are "+tot+" rooms in this realm. "+ "The actual map is being produced now.\n"); return 1; } /******************************************** * The files are checked, now make the map: * ********************************************/ status move_x(int ii) { int j,k; maxx=maxx-PX[ii]; for(j=0;j<=maxy;j++) { for(k=maxx;k>=-PX[ii];k--) xy[k][j] = xy[k+PX[ii]][j]; for(k=0;k<-PX[ii];k++) xy[k][j]=0; } return 1; } status move_y(int ii) { int j,k; maxy=maxy-PY[ii]; for(j=0;j<=maxx;j++) { for(k=maxy;k>=-PY[ii];k--) xy[j][k] = xy[j][k+PY[ii]]; for(k=0;k<-PY[ii];k++) xy[j][k]=0; } return 1; } status make_actual_map() { int i,j,k,l,m,n,t,x,y; mixed *vx,*vy, *done; string *tmp,s,s1,s2; done=allocate(sizeof(SYMBOL_ROOM));done=({}); tmp=allocate(sizeof(SYMBOL)); vx=allocate(tot); vy=allocate(tot); x=0; y=0; t=0; n=0; maxx=0; maxy=0; xy[0][0]="S"; while(files[t*2] && files[t*2]!="") { tmp=explode((string)files[t*2+1]," "); for(i=0;i<9;i++) { if(tmp[i]!="0") { if(tmp[i]=="1") { if(i!=8) n++; if(x+PX[i]<0) { x-=PX[i]; move_x(i); for(m=n;m>t;m--) vx[m]=vx[m]-PX[i]; } if(y+PY[i]<0) { y-=PY[i]; move_y(i); for(m=n;m>t;m--) vy[m]=vy[m]-PY[i]; } if(i==8) { xy[x+PX[i]][y+PY[i]] = "E"; } else { j=0; s=files[t*2]->short(); while(j<sizeof(SOMEROOM) && sscanf(s,"%s"+capitalize(SOMEROOM[j])+"%s",s1,s2)==0 && sscanf(s,"%s"+SOMEROOM[j]+"%s",s1,s2)==0) j++; if(j<sizeof(SOMEROOM)) { xy[x+PX[i]][y+PY[i]] = SYMBOL_ROOM[j]; if(MA(SYMBOL_ROOM[j],done)==-1) { done+=({SYMBOL_ROOM[j],}); map+=SYMBOL_ROOM[j]+": "+capitalize(SOMEROOM[j])+"\n"; } } else { xy[x+PX[i]][y+PY[i]]="x"; } vx[n]=x+PX[i]; vy[n]=y+PY[i]; } if(x+PX[i]>maxx) maxx=x+PX[i]; if(y+PY[i]>maxy) maxy=y+PY[i]; k=x+(int)PX[i]/2; l=y+(int)PY[i]/2; if(xy[k][l]==SYMBOL[1] || xy[k][l]==SYMBOL[3]) xy[k][l]="X"; else xy[k][l] = SYMBOL[i]; } else { xy[x+(int)PX[i]/2][y+(int)PY[i]/2] = SYMBOL[i]; } } } t++; x=vx[t]; y=vy[t]; } return 1; } status start_map() { string creator; int i; files=allocate(300); for(i=0;i<sizeof(files);i++) files[i]=""; creator=call_other(this_player(),"query_real_name"); if(call_other(this_player(),"query_security_level")<20) { write("You're not allowed to use this tool!.\n"); destruct(this_object()); return 1; } while(remove_call_out("destmap") > -1) remove_call_out("destmap"); map=""; make_file_string(); xy=allocate(tot); // 'tot' was calculated in 'make_file_string()' for(i=0;i<sizeof(xy);i++) xy[i]=allocate(80); move_object(this_object(),environment(find_living(creator))); make_actual_map(); convert_xy2map(); map=map+"\n ** Map created by "+capitalize(creator)+" on "+ctime()+" **\n"; write_file("/players/"+creator+"/"+LOGFILE,map); write("Tracker tells you: Done with map-making.\n"+ "Final MAP (logged to the file /players/"+creator+"/"+LOGFILE+"): \n"+map+"\n"); call_out("destmap",0,5); return 1; }