///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// simple maze-generation!
// Its really simple, if a room is flagged as a 1, it is enterable, if it is beside another room flagged with a 1
// that too becomes linked for movement.  If the room is a 2, it checks for up/down, in-which case, if it finds a 1 or a 2
// above or below it in Z value's, then movement up or down is available, (or both)
// Maze stems off nicely, if it reaches a point where it maxes out failed attempts, it moves to a new random location
// and starts generating another map from there.  In hopes that they infact-meet up somewhere.
// if it fails 10 times in a row, it aborts the generation where it is, logs it, and lets the maze work.
// if the maze at this point in time is completely broken, the player who auto-genned it will know, as it wont' be
// very usable.
// if the maze gen fails, broken becomes true, and it notifies the player that with it being broken, they *CANNOT*
// complete the maze, and will have to re-enter, and hope that the next one does not fail.
//
// The generation here is quick, and painful.  We want to ensure that the map is carefully designed as-to not be too
// generic.  Which is why the start-z/y/x exist, making each map alittle different from the last, based entirely off of
// how it selects the start-point, and the random direction it chooses to go.
//
// Memory intensity:  This system is very memory intensive, massive maps, being created on the fly, constantly.  This will
// need to have some-level of management, such as you cannot create a maze if you've recently been in one (like 30 minutes)
// stopping players from entering/exiting until they get the 'type' of map they want.  Only caveat for this is if the maze
// is marked as broken.  In that case, don't flag them.
//
// On topic of memory intensity.  To avoid massive cpu spiking, it would be recommended that the cooldown between mazes
// per player be a min of half an hour. 
//
// *Note:  If flagging a player, if they quit the maze before completion, or if they complete it, the wait time should
// always be the same.  Infact, quitters should most likely be lagged longer, just because they were part of it.
//
// If an entire group quits, at that point in time, the maze is deleted from memory.  Upon completion of the maze
// all players will be sent back to the summoning stone for the maze, including the person who entered the maze itself.
// summon stone should be approx 15/20 x/y coords away from a given maze.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Lexi::List<maze_data *>maze_list;						// keep track of our globally used mazes!

#define ROOM_VNUM_MAZE						4		// Like wilderness.  Makes life easier.

class maze_data {
	public: 
		maze_data() { sz = 0; sy = 0; sx = 0; actual_size = 0; mx = 0; broken = false;
			      level = 0; treasure = 0; repop = 0; rare_drop = 0; elite = false;
			      monsters_left = 0; bosses_left = 0; started = false;
			      puzzle_start = 0; puzzles_left = 0;
			    }
		~maze_data() { free_string(name);}
	private:
		vnum_t repop;
		vnum_t rare_drop;
		short maze[30][250][250];
		short puzzle[30][250][250];					// puzzles to go into the next room!
		short summon_x;							// the mazes X summon-stone location
		short summon_y;							// the mazes Y summon-stone location
		short sz;							// Start Z loc
		short sx;							// Start X loc
		short sy;							// Start Y loc
		short actual_size;						// actual size
		short mx;							// max size	(should be on-par with actual-size)
		short level;
		short treasure;
		short monsters_left;						// how many monsters are left (after each kill)
		short bosses_left;						// how many bosses are left!

		short mob_start;						// original mob counts
		short boss_Start;						// original boss counts

		short puzzle_start;						// how many puzzles will be in the maze
		short puzzles_left;						// how many puzzles are left!

		short players_in_maze;						// how many players are in the maze!

		const char *maze_name;						// name of the maze/dungeon your in!
		bool elite;
		bool broken;
		bool maze_started;
	public:
		short get_start_x() { return sx; }
		short get_start_y() { return sy; }
		short get_start_z() { return sz; }

		short get_summon_x() { return summon_x; }
		short get_summon_y() { return summon_y; }

		short get_players() { return players_in_maze; }
		short get_puzzles() { return puzzles_left; }
		short get_maze(short z, short x, short y) { return maze[z][x][y]; }	// (0-1-2 (hopefully it doesn't exceed the max))
		short get_size() { return actual_size; }
		short get_max() { return mx; }
		short get_level() {return level; }
		short get_monsters() { return monsters_left; }
		short get_bosses() { return bosses_left; }
		const char *get_name() { return maze_name; }
		bool  get_broken() { return broken; }
		bool  started() { return maze_started; }
		bool  get_elite() { return elite; }
		bool  get_broken() { return broken; }
		void  set_start() { maze_started = true; }
		void  kill_mob(CHAR_DATA *grp) { 				// done on raw-kill
					if(monsters_left > 0) {
						monsters_left--; 
						if(monsters_left == 0) {
							// insert leaderboard here (for ALL group members)
							if(elite) {
								// secondary leaderboard for elite monsters
							}
						}
					}
					return;
		}
		void kill_boss(CHAR_DATA *grp) {				// done on raw-kill
					if(bosses_left > 0) {
						bosses_left--; 
						if(bosses_left == 0) {
							// clearing dungeons = hardcore.
							// insert leaderboard here (for ALL group members)
							if(elite) {
								// secondary leaderboard for elite boss's
							}
						}
					}
					return;
		}

		/////////////////////////////////////////////////////////////////////////////////////////
		// Generates a puzzle so that players cannot pass until they have figure'd it out.
		// it can be anything from a saying, phrase, special command issue'd.
		// the puzzles are selected from lua scripts.
		//
		// lua-progs that are puzzles, their description is used not to describe its functionality
		// but should infact, be a puzzle, riddle, something for the players to figure out.
		//
		// puzzle's are marked as staff 3 in the lua.
		//
		// Puzzles are what make the the maze's worth-while.  Solving puzzles helps progress through
		// the map, aswell as get bonus's, leaderboard titles.  And all sorts of other fun-ness.
		// Note, after-awhile, the puzzles will be, well, easy, as they will start repeating, which
		// means we will have to write hundreds of puzzles, if not thousands to make this worth-while.
		// but hey, thats no worries, as it is *WELL* worth it.
		//
		void generate_puzzle(short z, short y, short z) {
			// puzzle will be the vnum of the puzzle chosen.

		}

		/////////////////////////////////////////////////////////////////////////////////////////
		// Spawn a mobile at position z/x/y, roughly mob_level, from repop_vnum, if marked elite
		// we increase stats.
		void spawn_mobile(short z, short x, short y, short mob_level, vnum_t repop_vnum, bool elite) {
			// 55 % chance of spawning a mobile.
			// with the size of mazes, (being up to 530 rooms) it seems to reason that
			// nomatter what, mobs are going to spawn.  And be quite nasty!
			// This should allow us to cap out on our mobs/bosses easily enough, most likely
			// with room-to-spare, but thats why we let the mobs wander!
			if(number_percent() > 55)
				return;

			if(mob_start == monsters_left)
				return;

			WILD_MOB *wmob = find_wild_pattern(repop_vnum);
			if(!wmob) return;

			int spawn = number_range(0,10);
			MOB_INDEX_DATA *mob = get_mob_index(wmob->vnum_list[spawn]);
			if(!mob) return;

			CHAR_DATA *instanced = create_mobile(mob);
			// move to the coordinates
			instanced->cord[CORD_Z] = z;
			instanced->cord[CORD_X] = x;
			instanced->cord[CORD_Y] = y;

			////////////////////////////////////////////////////////////////////////
			// Ensure that the instanced mobs will group up against the enemies.
			instanced->group = (repop_vnum+1); // should ensure their groupie-ness!


			char_to_room(get_room_index(ROOM_VNUM_MAZE), instanced);	// move into the maze

			// set the level
			instanced->level = number_range(mob_level-5, mob_level+5);
			if(instanced->level < 1) instanced->level = 1;

			// We want *ALL* of the mobs to be extremely hostile, so we go aggressive for good measure.
			if(!IS_SET(instanced->act, ACT_AGGRESSIVE)) SET_BIT(instanced->act, ACT_AGGRESSIVE);

			// Let the mobiles wander, this should help spread out the beasties nicely
			// especially if they all spawn at the very start of the maze, and not at the end of its
			// generation.  Eventually, the mobs should walk all over the place :)
			if(IS_SET(instanced->act, ACT_SENTINEL)) REMOVE_BIT(instanced->act, ACT_SENTINEL);

			// set our boss's.
			if(instanced->level == mob_level+5 && boss_left != boss_start) {
				if(!IS_SET(instanced->act, ACT_BOSS)) SET_BIT(instanced->act, ACT_BOSS);
				bosses_left++;
			}

			// increment our monsters.
			monsters_left++;

			// this fixes the stats with the new level and if a boss, with the new boss flag.
			correct_mobile(instanced);

			// equip the monsters with random gear so that it is worth while to kill these
			// creatures.  *Note:  If the mobs have a rare drops on them, this gets even
			// more interesting, as on kill, they risk creating a nice random object.
			maze_output(instanced);
			return;
		}

		/////////////////////////////////////////////////////////////////////////////////////////
		// This will populate the maze with mobs from the repop_vnum, which loads the spawns from
		// wild_mob list, normally reserved for patterns, is now being used here to help populate
		// the random maze.
		// mob_level assigns the approximate level of the mobs
		// repop_vnum pulls the respawned mobs from the pattern maps.
		// treasure-level is the approximate worth of the treasure (1-10, 10 being best)
		// rare_drop_vnum is the vnum of the object that will be the random-drop on the boss
		// mob in the dungeon.
		// elite means the players selected elite mobs when they summoned in their friends.
		//                         this means mobs are even stronger, and smarter.
		//                         aswell as improving the treasure (even if it was a 10, they get better)
		/////////////////////////////////////////////////////////////////////////////////////////
		// Maze generation as easy as maze->generate_maze(20,100,88, 1800, 325, 88, 10, 7, 25, 3, 5, 88, true, "Jaspers Dungeon of Territorial Doom");
		// we randomly generate the maze!
		// this is fun, smart, and overall, exciting.
		void generate_maze(short z, short x, short y, short sum_x, short sum_y, short mob_count, short boss_count, puzzle_count, short mob_level, vnum_t repop_vnum, short treasure_level, vnum_t rare_drop_vnum, bool elite, const char *name) {
			int xy, yy, zy;
			int max_size = 0;

			spawn_mobile(current_z, current_x, current_y, mob_level, repop_vnum, elite);

			////////////////////////////////////////////////////////////////////////
			// x/y/z variables just allocate our max-size(in total) they don't manage
			// how far east/west/up/down/north/south things will go.
			// those are maxed anyways.  However, we always ensure we are more then
			// taken-care of with our overall layout.
			// ensure our maximums are not exceeded
			if(x > 250) x = 250;
			if(y > 250) y = 250;
			if(z >  30) z = 30;
			maze_name = str_dup(name);

			mob_start = mob_count;
			boss_start = boss_count;
			puzzle_start = puzzle_count;

			////////////////////////////////////////////////////////////////////////
			// zero the map first. (safe practice before having fun)
			for(xy = 0; xy < x; xy++ ) {
				for(yy = 0; yy < y; yy++ ) {
					for(zy = 0; zy < z; zy++ ) {
						maze[x][y][z] = 0;
					}
				}
			}
			int counter = 0;
			int start_room_x, start_room_y, start_room_z;


			summon_x = sum_x;
			summon_y = sum_y;

			max_size == (x+y)+z;					// z feels left out ;) (making a joke with code)
			mx = max_size;						// set our 'supposed' to be size.
			start_room_x = number_range(0,x);
			start_room_y = number_range(0,y);
			start_room_z = number_range(0,z);

			////////////////////////////////////////////////////////////////////////
			// make that room in the maze exist!
			maze[start_room_z][start_room_x][start_room_y] = 1;

			// our start-room in the maze! (MUAHAHAHAHAHA)
			sz = start_room_z;
			sx = start_room_x;
			sy = start_room_y;

			// so we know where we are in the map!
			int current_x = start_room_x;
			int current_y = start_room_y;
			int current_z = start_room_z;

			int attempt = 0;
			int attempt_maxed 0;

			// Lets make the maze!
			for(;;) {

				int direction = number_range(0,6);
				bool failed = false;
				short jump_back = false;

				// map is done!  Reached our max-size!  Time to populate! (if we managed to breach it
				// with the jumpback code, then we say whatever, and carry on peacefully)
				if(count >= max_size) break;

				if(attempt == 6) {
					// failed 6 times, that means all exits around the person, are filled.
					// and it wouldn't progress anyfurther. (or it just had bad luck
					// randomizing the same number, but, to prevent a potential lockup
					// we move the current_x/y/z locations to a random spot, and hope
					// it manages to link up with the rest.  Else wise, the dungeon
					// could be pooched!
					attempt = 0;				// reset attempt count!
					attempt_maxed++;			// maxed our attempt 6 times
										// now we count that.
										// if we have a massive glitch
										// we'd like to know!

					if(attempt_max == 10)			// we maxed our attempts 10 times
					{					// now we do some fancy logging when this happens.
						broken = true;			// yup, its broken.
						log_string("[MAZE GEN] %s reached max generation attempts, with a count of %d of %d", __PRETTY_FUNCTION__, count, max_size);
						break;				// we don't want to lockup
					}					// so we break the generation
										// and hope that all is well.
					current_x = number_range(0,x);
					current_y = number_range(0,y);
					current_z = number_range(0,z);
				}

				// here is where we get.... creepy!
				jump_back = number_range(0,11);

				///////////////////////////////////////////////////////////////////////////////////////////////////////
				// Jumping back, this got the name because it creates stretch's off of the main-path and then jumps
				// back to the path, and carries on with the normal map generation.  Sick little plan.
				// This will be interesting.
				// *Note: east/west/north/south directions care if a room is already-set, and won't move into it.
				// however, up/down don't care, and will move into it, and change the exits to 2, so it knows it can
				// go up or down.
				// the bonus stretches can head off up to 12 rooms (including the original off-shoot)
				// the extra stretches are a percent chance to happen, they do not always occur when jump-back takes
				// place, this should help create little balls of extra-joy.
				///////////////////////////////////////////////////////////////////////////////////////////////////////
				if(jump_back == 4) {								// why 4?  Why not!
					short where = number_range(0,3);
					short max_p = number_range(3,11);
					// change in x/y/z location.
					switch(where) {
						// NORTH/SOUTH MANIPULATION
						default:
						case 0:
						if(number_range(0,1) == 1) {
							current_x++;
							if(current_x != 250) {
								if(maze[current_z][current_x][current_y] == 0) {
									maze[current_z][current_x][current_y] = 1;
									count++;
									if(number_percent() > number_range(78,100))
									for(int p = 0; p < max_p; p++) {
										if(current_x+p < 250) {
											if(maze[current_z][current_x+p][current_y] == 0) {
												maze[current_z][current_x+p][current_y] = 1;
												count++;
												spawn_mobile(current_z, current_x+p, current_y, mob_level, repop_vnum, elite);
										}
									}
								}

							}
							current_x--; // go back to our original x location and continue from there!
						} else {
							current_x++;
							if(current_x != 250) {
								if(maze[current_z][current_x][current_y] == 0) {
									maze[current_z][current_x][current_y] = 1;
									count++;
									if(number_percent() > number_range(78,100))
									for(int p = 0; p < max_p; p++) {
										if(current_x-p > -1) {
											if(maze[current_z][current_x-p][current_y] == 0) {
												maze[current_z][current_x-p][current_y] = 1;
												count++;
												spawn_mobile(current_z, current_x-p, current_y, mob_level, repop_vnum, elite);
										}
									}
								}

							}
							current_x--; // go back to our original x location and continue from there!
						}
						// EAST/WEST CHANGING
						case 1:
						if(number_range(0,1) == 1) {
							current_y++;
							if(current_y != 250) {
								if(maze[current_z][current_x][current_y] == 0) {
									maze[current_z][current_x][current_y] = 1;
									count++;
									if(number_percent() > number_range(78,100))
									for(int p = 0; p < 5; max_p++) {
										if(current_y+p < 250) {
											if(maze[current_z][current_x][current_y+p] == 0) {
												maze[current_z][current_x][current_y+p] = 1;
												count++;
												spawn_mobile(current_z, current_x, current_y+p, mob_level, repop_vnum, elite);
										}
									}
								}

							}
							current_y--; // go back to our original x location and continue from there!
						} else {
							current_y++;
							if(current_y != 250) {
								if(maze[current_z][current_x][current_y] == 0) {
									maze[current_z][current_x][current_y] = 1;
									count++;
									if(number_percent() > number_range(78,100))
									for(int p = 0; p < max_p; p++) {
										if(current_y-p > -1) {
											if(maze[current_z][current_x][current_y-p] == 0) {
												maze[current_z][current_x][current_y-p] = 1;
												count++;
												spawn_mobile(current_z, current_x, current_y-p, mob_level, repop_vnum, elite);
										}
									}
								}

							}
							current_y--; // go back to our original x location and continue from there!
						}
						///////////////////////////////////////////////////////////////////////////////////////////
						// UP/DOWN MANIPULATION..  THIS *IS* VITAL AND SCARY AT THE SAME TIME!
						case 2:
						if(number_range(0,1) == 1) {
							current_z++;
							if(current_z != 30) {
								maze[current_z][current_x][current_y] = 2;
								count++;
								if(number_percent() > number_range(78,100))
								for(int p = 0; p < max_p; p++) {
									if(current_x+p < 30) {
										maze[current_z+p][current_x][current_y] = 2;
										count++;
										spawn_mobile(current_z+p, current_x, current_y, mob_level, repop_vnum, elite);
								}
							}
							current_z--; // go back to our original x location and continue from there!
						} else {
							current_z++;
							if(current_z != 30) {
								maze[current_z][current_x][current_y] = 2;
								count++;
								if(number_percent() > number_range(78,100))
								for(int p = 0; p < max_p; p++) {
									if(current_z-1p > -1) {
										maze[current_z-p][current_x][current_y] = 2;
										count++;
										spawn_mobile(current_z+p, current_x, current_y, mob_level, repop_vnum, elite);
								}

							}
							current_z--; // go back to our original x location and continue from there!
						}
						break;
					}
				}

				///////////////////////////////////////////////////////////////////////////////////////////////////////
				// Continuing the insanity here:
				// Our now official goal, if we did, or did not stem off, is to now change our direction, and parse
				// through and hopefully generate a really cool new design/layout for the overall map
				// because of the treeing system above, we hope to see many sub-paths carry off from the original
				// path.. Perfect to hide evil little minions in them.
				///////////////////////////////////////////////////////////////////////////////////////////////////////
				switch(direction) {
					default:
					case DIR_NORTH:
						// cannot go any-further north!
						if(current_x+1 == 250){
							failed = true;
							break;
						}
						if(maze[current_x][current_x+1][current_y] == 0) {
							current_x++;
							maze[current_z][current_x][current_y] = 1;
							spawn_mobile(current_z, current_x, current_y, mob_level, repop_vnum, elite);
							// here we go with a chance to make an extra direction (helps space-out the map)
							if(current_x+1 == 250) break;	// not failed because we did increment.
							if(number_range(0,5) == number_range(0,5)) {
								if(maze[current_z][current_x+1][current_y] == 0) {
									current_x++;								
									count++;	// so we keep our counts properly.
									maze[current_z][current_x][current_y] = 1;
								}
							}
						} else { failed = true; }
						break;
					case DIR_SOUTH:
						// cannot go any-further north!
						if(current_x-1 == -1){
							failed = true;
							break;
						}
						if(maze[current_x][current_x-1][current_y] == 0) {
							current_x--;
							maze[current_z][current_x][current_y] = 1;
							spawn_mobile(current_z, current_x, current_y, mob_level, repop_vnum, elite);
							// here we go with a chance to make an extra direction (helps space-out the map)
							if(current_x-1 == -1) break;	// not failed because we did increment.
							if(number_range(0,5) == number_range(0,5)) {
								if(maze[current_z][current_x-1][current_y] == 0) {
									current_x--;								
									count++;	// so we keep our counts properly.
									maze[current_z][current_x][current_y] = 1;
								}
							}
						} else { failed = true; }
						break;
					case DIR_EAST:
						// cannot go any-further north!
						if(current_y+1 == 250){
							failed = true;
							break;
						}
						if(maze[current_z][current_x][current_y+1] == 0) {
							current_y++;
							maze[current_z][current_x][current_y] = 1;
							spawn_mobile(current_z, current_x, current_y, mob_level, repop_vnum, elite);
							// here we go with a chance to make an extra direction (helps space-out the map)
							if(current_y+1 == 250) break;	// not failed because we did increment.
							if(number_range(0,5) == number_range(0,5)) {
								if(maze[current_z][current_x][current_y+1] == 0) {
									current_y++;								
									count++;	// so we keep our counts properly.
									maze[current_z][current_x][current_y] = 1;
								}
							}
						} else { failed = true; }
						break;
					case DIR_WEST:
						// cannot go any-further north!
						if(current_y-1 == -1){
							failed = true;
							break;
						}
						if(maze[current_z][current_x][current_y-1] == 0) {
							current_y++;
							maze[current_z][current_x][current_y] = 1;
							spawn_mobile(current_z, current_x, current_y, mob_level, repop_vnum, elite);
							// here we go with a chance to make an extra direction (helps space-out the map)
							if(current_y-1 == 250) break;	// not failed because we did increment.
							if(number_range(0,5) == number_range(0,5)) {
								if(maze[current_z][current_x][current_y-1] == 0) {
									current_y--;								
									count++;	// so we keep our counts properly.
									maze[current_z][current_x][current_y] = 1;
								}
							}
						} else { failed = true; }
						break;
					case DIR_UP:
						// cannot go any-further north!
						if(current_z+1 == 30){
							failed = true;
							break;
						}

						// up/down don't care if the value is 0, it creates a up/down link anyways!
						// helps create a random-link.
						current_z++;
						spawn_mobile(current_z, current_x, current_y, mob_level, repop_vnum, elite);
						maze[current_z][current_x][current_y] = 2; // 2 means it links up!
						// here we go with a chance to make an extra direction (helps space-out the map)
						if(current_z+1 == 30) break;	// not failed because we did increment.
						if(number_range(0,5) == number_range(0,5)) {
							current_z++;								
							count++;	// so we keep our counts properly.
							maze[current_z][current_x][current_y] = 2;
						}
						break;
					case DIR_DOWN:
						// cannot go any-further north!
						if(current_z-1 == -1){
							failed = true;
							break;
						}

						// up/down don't care if the value is 0, it creates a up/down link anyways!
						// helps create a random-link.
						current_z--;
						spawn_mobile(current_z, current_x, current_y, mob_level, repop_vnum, elite);
						maze[current_z][current_x][current_y] = 2; // 2 means it links up or down (or both)
						// here we go with a chance to make an extra direction (helps space-out the map)
						if(current_z+1 == 30) break;	// not failed because we did increment.
						if(number_range(0,5) == number_range(0,5)) {
							current_z--;								
							count++;	// so we keep our counts properly.
							maze[current_z][current_x][current_y] = 2;
						}
						break;
				}

				if(!failed)
					count++;
				else
					attempt++;		// saves us from infinate loop!

			}

			actual_size = count;
			maze_list.push_back(this);
		}
};

////////////////////////////////////////////////////////////////////////////////////////
// display some minor information about the maze in question.
COMMAND(do_maze) {
	if(ch->in_maze == NULL)	{
		ch->Sendf("But your not in a maze!\n\r");
		return;
	}

	maze_data *maze = ch->in_maze;

	if(NullString(argument)) {
		ch->Sendf("Syntax: maze <start|summon|quit|info>\n\r");
		return;
	}

	if(!str_cmp(argument, "summon")) {
		if(maze->started()) {
			ch->Sendf("You cannot summon once the maze has started!\n\r");
			return;
		}

		// pull the groupies to the maze from the summoning stone.
		FOREACH(Lexi::List<CHAR_DATA *ch>, player_list, player_iter) {
			CHAR_DATA *groupie = (*player_iter);
			if(is_same_group(ch, groupie) && groupie->x == maze->summon_x && groupie->y == maze->summon_y) {
				if(groupie->recent_maze != 0) continue;
				char_from_room(groupie);
				char_to_room(get_room_index(4), ch);
				groupie->cord[CORD_X] = ch->cord[CORD_X];
				groupie->cord[CORD_Y] = ch->cord[CORD_Y];	
				groupie->cord[CORD_Z] = ch->cord[CORD_Z];
				groupie->in_maze = ch->in_maze;
				do_look(groupie, "auto");
				in_maze->get_players()++;		// increment the players (crazy technique here)
			}
		}

	}

	if(!str_cmp(argument, "start")) {
		if(maze->started()) {
			ch->Sendf("The maze has already been started!  Hurry up!\n\r");
			return;
		}
		maze->set_start();
		do_function(ch, &do_gtell, "Maze started up!  Prepare yourselves %s!", ch->rebel ? "Comrades" : "my good chums");
		return;
	}

	// just know alittle about your dungeon of ultimate doom!
	if(!str_cmp(argument, "info")) {
		ch->Sendf("\n\r+---------------------[ %s%s ]---------------------+\n\r", maze->get_broken ? "[Broken] " : "", maze->get_name());
		ch->Sendf(" [ %s ] [Level: %d]", maze->get_elite() ? "Elite" : "Normal", maze->get_level());
		ch->Sendf(" [Bosses Left:   %d]", maze->get_bosses());
		ch->Sendf(" [Monsters Left: %d]", maze->get_monsters());
		ch->Sendf(" [Puzzles Left: %d]", maze->get_puzzles());
		return;
	}

	if(!str_cmp(argument, "quit")) {
		do_function(ch, &do_gtell, "Sorry %s, but I have to bail!  %s.", ch->rebel ? "my friends" : "guys", ch->rebel ? "Cheers" : "Good-bye");
		// is it really that simple?  Yes, because we aren't modifying the x/y locations, it checks to see if your in_maze, if so.
		// it reads and does everything differently!  This will restore you back to the worldmap. where you entered (summoning stone)
		char_from_room(ch);
		char_to_room(get_room_index(3), ch);			// wilderness!

		// send them back to the summon stone!
		ch->x = in_maze->get_summon_x();
		ch->y = in_maze->get_summon_y();
		ch->in_maze = NULL;
		ch->recent_maze = 35;					// 35 ticks until you can enter a new one
									// you cannot be summoned in unless you have 0
		return;
	}

	ch->Sendf("What option is that!\n\r");
	return;
}

////////////////////////////////////////////////////////////////////////////////////////
// Just display what mazes are open.  Since they are linked from the world-map
// and are instanced *PER* group, we should see plenty of these open.
COMMAND(cmd_mazelist) {
	BUFFER *output;
	int count = 0;
	output = new_buf();
	BufPrintf(output, "Mazes currently in-use!\n\r");
	FOREACH(Lexi::List<maze_data *>, maze_list, maze_iter) {
		maze_data *maze;
		BufPrintf(output, "| %3d: | Start: z%5d x%5d y%5d | Max size: %5d | Actual Size: %5d | Broken: %5s|\n\r", count, maze->get_start_z(), maze->get_start_x(), maze->get_start_y(), maze->get_max(), maze->get_broken() ? "Yes" : "No");
		count++;
	}

	BufPrintf(output, "There are currently %d mazes in-use!\n\r", count);
	page_to_char(buf_string(output), ch);
	free_buf(output);
	return;
}