/* Gendi's rdig snippet, originally implemented on Hunters Network (http://www.hunters-network.com) Written at first for making a set of rooms from a prototype string, e.g. for SWR2's shipcode However was later adapted as an rdig function. This obviously has further uses than just do_rdig, but that is up to you Currently problems: No diagonal directions The start vnum must be followed by enough free vnums in order to work This can be changed, but you'll have to do that yourself ;) This is NOT easy to understand Probably many other things. The room and exit flags will probably not fit your MUD Written on SWR, so SMAUG 1.4a coders will require work I am 99% certain this will NOT compile on your MUD without extra work by you. The code was not written to be released, don't expect it to be nice to you! Here is the brief description given to the MUD I implemented it on, they got by ;) If you have further questions, plz mailto:gendi@gendi.co.uk syntax : rdig min level 102? 103? what it does.... god help me, can I explain this? Well, lets try a few examples... Key: s=startroom, -=exit, x=room rdig eeee s-x-x-x-x rdig nesw x-x | | s-x rdig ense x | s-x-x rdig eec1nneeessmw1 using a marker x-x-x-x | | x x | | s-x-x-----x Okay, what did you see above? Obvious n, s, e, w, d and u go in those directions and create rooms. c creates a marker in that room (0-9, can be reused). m returns to a previously marked room in the direction specified. Thats it. Okay, I lied, that was the simple bit. Also you can use rdig to set room flags and exit flags. room flags are set using f. period at end is important. exit flags are set using x. e.g. rdig exdcl.nfp.se creates a rooms east, then a room north with the exit between the two being isdoor, closed, locked. Sets the north room with the flags prison. Then comes back south then creates a room east room flags:- very few right now, just p=prison and s=spacecraft exit flags:- d ISDOOR c CLOSED l LOCKED b BASE v BLASTDOOR k CUTPROOF p BASHPROOF s SECRET w SWIM f FLY h HIDDEN m NOMOB */ //Add in mud.h //With other typedefs typedef struct coord_data COORD_DATA; //used with rdig //Above struct room_index_data add struct coord_data { int x; int y; int z; }; //In struct room_index_data add COORD_DATA * coords; //If you don't like the use of COORD_DATA then write your own version //It just made my life easier at the time //Add required stuff for the new command do_rdig (you may wish to change //the function name if you are using the other rdig snippet). // Gendi's rdig snippet, originally implemented on Hunters Network (http://www.hunters-network.com) // used to go through and destroy rooms created if an error has occured during creation void rdig_destroy(ROOM_INDEX_DATA *startroom, int end, int firstdir) { int x; ROOM_INDEX_DATA *room; EXIT_DATA *xit; if ( firstdir != DIR_SOMEWHERE && (xit = get_exit(startroom, firstdir)) != NULL ) extract_exit(startroom, xit); for( x = startroom->vnum+1; x <= end; x++) { room = get_room_index(x); if ( room ) delete_room( room ); } } // Gendi's rdig snippet, originally implemented on Hunters Network (http://www.hunters-network.com) // count the number of rooms needed in rdig // use this before rdig to make sure you have enough rooms in a straight line // to allow rdig to work (currently rooms must be linear, i.e. 1-10. 1-2 with 4-11 // is not allowed // I could return 0 when a problem occurs like an unknown identifier int rdig_count(char *line) { int count=0, x=0; while( line[x] && line[x] != '\0') { switch( LOWER(line[x]) ) { case 'n': case 's': case 'e': case 'w': case 'u': case 'd': //moving to new room so count it count++; break; case 'm': //going back to a previous marker so skip room x++; break; case 'x': case 'f': //skip through flags //must do this as some flags look like directions! x++; while( line[x] && line[x] != '\0' && line[x] != '.' ) x++; break; // option 1, just ignore anything unknown default: //not moving room so move along the string break; // end option 1 // option 2, return false when unknown found /* case 'c': //creating a marker requires no moving break; default: return 0; */ // end option 2 } //if check should never be false, but better to check! if( line[x] && line[x] != '\0' ) x++; } return count; } // Gendi's rdig snippet, originally implemented on Hunters Network (http://www.hunters-network.com) // room linking function ROOM_INDEX_DATA * rdig_link_room(ROOM_INDEX_DATA *room, ROOM_INDEX_DATA *toroom, int edir, int vnum, int exit_flags, ROOM_INDEX_DATA *startroom) { EXIT_DATA *xit, *rxit; ROOM_INDEX_DATA *troom = toroom; int x, y, z; // find coords we are going to if ( !room || !room->coords ) // panic { bug("LINK_ROOM: No coords created for room!"); return NULL; } x = room->coords->x; y = room->coords->y; z = room->coords->z; switch(edir) { case DIR_NORTH: y++; break; case DIR_SOUTH: y--; break; case DIR_EAST: x++; break; case DIR_WEST: x--; break; case DIR_UP: z++; break; case DIR_DOWN: z--; break; /*case DIR_NORTHEAST: y++; x++; break; case DIR_NORTHWEST: y++; x--; break; case DIR_SOUTHEAST: y--; x++; break; case DIR_SOUTHWEST: y--; x--; break;*/ } // If no room supplied then look to see if there is a room in that // direction on the grid, and if so, use it for troom if( !troom ) { int tint; for( tint = startroom->vnum; tint < vnum; tint++) { troom = get_room_index(tint); if( !troom || !troom->coords ) continue; if( troom->coords->x == x && troom->coords->y == y && troom->coords->z == z ) { break; } troom = NULL; } } if( !troom ) { troom = make_room( vnum, NULL );// could use startroom here, but I don't want to copy name, description, flags troom->sector_type = startroom->sector_type; troom->light = startroom->light; troom->tunnel = startroom->tunnel; troom->area = startroom->area; CREATE( troom->coords, COORD_DATA, 1 ); troom->coords->x = x; troom->coords->y = y; troom->coords->z = z; } if ( !get_exit(room, edir) ) { if ( get_exit(troom, rev_dir[edir] ) ) return NULL; xit = make_exit( room, troom, edir ); xit->keyword = STRALLOC( "" ); xit->description = STRALLOC( "" ); xit->key = -1; xit->exit_info = exit_flags; rxit = make_exit( troom, room, rev_dir[edir] ); rxit->keyword = STRALLOC( "" ); rxit->description = STRALLOC( "" ); rxit->key = -1; rxit->exit_info = exit_flags; } if ( exit_flags ) { instaroom(startroom->area, room, TRUE); instaroom(startroom->area, troom, TRUE); } return troom; } // Gendi's rdig snippet, originally implemented on Hunters Network (http://www.hunters-network.com) // line is the string with creation data in char *rdig( ROOM_INDEX_DATA *startroom, char *line) { ROOM_INDEX_DATA *room; int markers[10]; //for simplicity just have an array that allows for 10 markers (0-9) int i, nextvnum, exit_flags, rooms, marker; char *buf2; char buf[MAX_STRING_LENGTH]; char tchar[2]; int firstdir = DIR_SOMEWHERE, edir = DIR_SOMEWHERE; room = startroom; nextvnum = startroom->vnum + 1; exit_flags = 0; tchar[0] = '0'; tchar[1] = '\0'; CREATE( startroom->coords, COORD_DATA, 1 ); startroom->coords->x = 0; startroom->coords->y = 0; startroom->coords->z = 0; rooms = rdig_count(line); //used with option 2 of rdig_count /*if ( !rooms ) return "Unknown flag found or no rooms would be created.\n\r";*/ //end option 2 //check enough rooms available if ( startroom->area->hi_r_vnum - rooms < startroom->vnum ) return "Not enough rooms left in your area.\n\r"; for ( i = startroom->vnum + 1; i <= startroom->vnum + rooms; i++) { if ( get_room_index(i) ) return "Not enough rooms available\n\r"; } for ( i = 0; line[i] && line[i] != '\0'; i++) { sprintf( buf, "character %c", line[i]); // check next letter switch(LOWER(line[i])) { case 'n': /*if( line[i+1] && line[i+1] != '\0' && line[i+1] = 'e' ) { edir = DIR_NORTHEAST; i++; } else if( line[i+1] && line[i+1] != '\0' && line[i+1] = 'w' ) { edir = DIR_NORTHEWST; i++; } else*/ edir = DIR_NORTH; room = rdig_link_room(room, NULL, edir, nextvnum++, exit_flags, startroom); exit_flags = 0; break; case 's': /*if( line[i+1] && line[i+1] != '\0' && line[i+1] = 'e' ) { edir = DIR_SOUTHEAST; i++; } else if( line[i+1] && line[i+1] != '\0' && line[i+1] = 'w' ) { edir = DIR_SOUTHEWST; i++; } else*/ edir = DIR_SOUTH; room = rdig_link_room(room, NULL, edir, nextvnum++, exit_flags, startroom); exit_flags = 0; break; case 'e': edir = DIR_EAST; room = rdig_link_room(room, NULL, edir, nextvnum++, exit_flags, startroom); exit_flags = 0; break; case 'w': edir = DIR_WEST; room = rdig_link_room(room, NULL, edir, nextvnum++, exit_flags, startroom); exit_flags = 0; break; case 'u': edir = DIR_UP; room = rdig_link_room(room, NULL, edir, nextvnum++, exit_flags, startroom); exit_flags = 0; break; case 'd': edir = DIR_DOWN; room = rdig_link_room(room, NULL, edir, nextvnum++, exit_flags, startroom); exit_flags = 0; break; case 'x': exit_flags = 0; i++; while( line[i] && line[i] != '.' && line[i] != '\0' ) { switch(LOWER(line[i])) { case 'd': SET_BIT(exit_flags, EX_ISDOOR); break; case 'c': SET_BIT(exit_flags, EX_CLOSED); break; case 'l': SET_BIT(exit_flags, EX_LOCKED); break; case 'b': SET_BIT(exit_flags, EX_BASE); break; case 'v': SET_BIT(exit_flags, EX_BLASTDOOR); break; case 'k': SET_BIT(exit_flags, EX_CUTPROOF); break; case 'p': SET_BIT(exit_flags, EX_BASHPROOF); break; case 's': SET_BIT(exit_flags, EX_SECRET); break; case 'w': SET_BIT(exit_flags, EX_SWIM); break; case 'f': SET_BIT(exit_flags, EX_FLY); break; case 'h': SET_BIT(exit_flags, EX_HIDDEN); break; case 'm': SET_BIT(exit_flags, EX_NOMOB); break; default: sprintf( buf, "Uknown eXit flag %c\n\r", line[i]); buf2 = STRALLOC(buf); rdig_destroy(startroom, nextvnum, firstdir); return buf2; } i++; } break; case 'f': i++; while( line[i] && line[i] != '.' && line[i] != '\0' ) { switch(LOWER(line[i])) { case 's': SET_BIT(room->room_flags, ROOM_SPACECRAFT); break; case 'p': SET_BIT(room->room_flags2, ROOM2_PRISON); break; // All the other suitable room flags default: sprintf( buf, "Uknown room Flag %c\n\r", line[i]); buf2 = STRALLOC(buf); rdig_destroy(startroom, nextvnum, firstdir); return buf2; } i++; } break; case 'c': tchar[0] = line[++i]; marker = atoi(tchar); markers[marker] = room->vnum; // remember markers can to reused. break; case 'm': tchar[0] = line[++i]; edir = get_dir(tchar); if( edir == DIR_SOMEWHERE || ( edir == DIR_NORTH && tchar[0] != 'n' ) ) { rdig_destroy(startroom, nextvnum, firstdir); return "Bad direction for marker\n\r"; } tchar[0] = line[++i]; if ( !is_number(tchar) ) return "Bad number for marker\n\r"; marker = atoi(tchar); if ( !markers[marker] || !get_room_index(markers[marker]) ) { sprintf( buf, "No marker stored at %d\n\r", marker); buf2 = STRALLOC(buf); rdig_destroy(startroom, nextvnum, firstdir); return buf2; } rdig_link_room(room, get_room_index(markers[marker]), edir, ++nextvnum, exit_flags, startroom); exit_flags = 0; break; // default not reached when option 2 of rdig_count used default: sprintf( buf, "Unknown identifier %c\n\r", line[i]); buf2 = STRALLOC(buf); rdig_destroy(startroom, nextvnum, firstdir); return buf2; } if ( firstdir == DIR_SOMEWHERE && edir != DIR_SOMEWHERE ) firstdir = edir; if ( !room ) { return "There seems to have been a problem and the rooms cannot be created\n\rRemember exits cannot be created where one already exists\n\r"; rdig_destroy(startroom, nextvnum, firstdir); } } return NULL; // returning NULL shows no problems occured, so no error message sent } // Gendi's rdig snippet, originally implemented on Hunters Network (http://www.hunters-network.com) void do_rdig( CHAR_DATA *ch, char *argument ) { char *buf; char arg[MAX_STRING_LENGTH]; if ( !ch->pcdata || !ch->pcdata->area ) { send_to_char("You don't have an area assigned.\n\r", ch); return; } if ( ch->pcdata->area != ch->in_room->area ) { send_to_char("You are not in your area.\n\r", ch); return; } argument = one_argument( argument, arg ); if ( !arg || arg[0] == '\0' ) { send_to_char("You must specify a creation line.\n\r", ch); return; } buf = rdig( ch->in_room, arg); if ( !buf ) send_to_char("Done.", ch); else send_to_char( buf, ch); return; }