2008-04-14 20:32:21 +00:00
|
|
|
/**************************************************************************
|
|
|
|
|
* File: asciimap.c Part of tbaMUD *
|
|
|
|
|
* Usage: Generates an ASCII map of the player's surroundings. *
|
|
|
|
|
* *
|
|
|
|
|
* All rights reserved. See license for complete information. *
|
|
|
|
|
* *
|
|
|
|
|
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
|
|
|
|
|
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
|
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "conf.h"
|
|
|
|
|
#include "sysdep.h"
|
|
|
|
|
|
|
|
|
|
#include "structs.h"
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
#include "comm.h"
|
|
|
|
|
#include "interpreter.h"
|
|
|
|
|
#include "handler.h"
|
|
|
|
|
#include "db.h"
|
|
|
|
|
#include "spells.h"
|
|
|
|
|
#include "house.h"
|
|
|
|
|
#include "constants.h"
|
|
|
|
|
#include "dg_scripts.h"
|
|
|
|
|
#include "asciimap.h"
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
* Begin Local (File Scope) Defines and Global Variables
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
/* Do not blindly change these values, as many values cause the map to stop working - backup first */
|
|
|
|
|
#define CANVAS_HEIGHT 19
|
|
|
|
|
#define CANVAS_WIDTH 51
|
|
|
|
|
#define LEGEND_WIDTH 15
|
|
|
|
|
|
|
|
|
|
#define DEFAULT_MAP_SIZE CONFIG_MAP_SIZE
|
|
|
|
|
|
|
|
|
|
#define MAX_MAP_SIZE (CANVAS_WIDTH - 1)/4
|
|
|
|
|
#define MAX_MAP CANVAS_WIDTH
|
|
|
|
|
|
|
|
|
|
#define MAX_MAP_DIR 6
|
|
|
|
|
#define MAX_MAP_FOLLOW 4
|
|
|
|
|
|
|
|
|
|
#define SECT_EMPTY 30 /* anything greater than num sect types */
|
|
|
|
|
#define SECT_STRANGE (SECT_EMPTY + 1)
|
|
|
|
|
#define SECT_HERE (SECT_STRANGE + 1)
|
|
|
|
|
|
|
|
|
|
#define DOOR_NS -1
|
|
|
|
|
#define DOOR_EW -2
|
|
|
|
|
#define DOOR_UP -3
|
|
|
|
|
#define DOOR_DOWN -4
|
|
|
|
|
#define VDOOR_NS -5
|
|
|
|
|
#define VDOOR_EW -6
|
|
|
|
|
#define DOOR_NONE -7
|
|
|
|
|
#define NUM_DOOR_TYPES 7
|
|
|
|
|
|
|
|
|
|
#define MAP_CIRCLE 0
|
|
|
|
|
#define MAP_RECTANGLE 1
|
|
|
|
|
|
|
|
|
|
#define MAP_NORMAL 0
|
|
|
|
|
#define MAP_COMPACT 1
|
|
|
|
|
|
|
|
|
|
struct map_info_type
|
|
|
|
|
{
|
|
|
|
|
int sector_type;
|
|
|
|
|
char disp[20];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct map_info_type door_info[] =
|
|
|
|
|
{
|
|
|
|
|
{ DOOR_NONE, " " },
|
|
|
|
|
{ VDOOR_EW, " @m+@n " },
|
|
|
|
|
{ VDOOR_NS, " @m+@n "},
|
|
|
|
|
{ DOOR_DOWN, "@r-@n " },
|
|
|
|
|
{ DOOR_UP, "@r+@n " },
|
|
|
|
|
{ DOOR_EW, " - " },
|
|
|
|
|
{ DOOR_NS, " | " }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct map_info_type compact_door_info[] =
|
|
|
|
|
{
|
|
|
|
|
{ DOOR_NONE, " " },
|
|
|
|
|
{ VDOOR_EW, " @m+@n " },
|
|
|
|
|
{ VDOOR_NS, " @m+@n "},
|
|
|
|
|
{ DOOR_DOWN, "@r-@n" },
|
|
|
|
|
{ DOOR_UP, "@r+@n" },
|
|
|
|
|
{ DOOR_EW, "-" },
|
|
|
|
|
{ DOOR_NS, " | " }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Add new sector types below for both map_info and world_map_info */
|
|
|
|
|
/* The last 3 MUST remain the same, although the symbol can be changed */
|
|
|
|
|
/* New sectors also need to be added to the perform_map function below */
|
|
|
|
|
static struct map_info_type map_info[] =
|
|
|
|
|
{
|
|
|
|
|
{ SECT_INSIDE, "@c[@n.@c]@n" }, /* 0 */
|
|
|
|
|
{ SECT_CITY, "@c[@wC@c]@n" },
|
|
|
|
|
{ SECT_FIELD, "@c[@g,@c]@n" },
|
|
|
|
|
{ SECT_FOREST, "@c[@gY@c]@n" },
|
|
|
|
|
{ SECT_HILLS, "@c[@Mm@c]@n" },
|
|
|
|
|
{ SECT_MOUNTAIN, "@c[@rM@c]@n" }, /* 5 */
|
|
|
|
|
{ SECT_WATER_SWIM, "@c[@c~@c]@n" },
|
|
|
|
|
{ SECT_WATER_NOSWIM, "@c[@b=@c]@n" },
|
|
|
|
|
{ SECT_FLYING, "@c[@C^@c]@n" },
|
|
|
|
|
{ SECT_UNDERWATER, "@c[@bU@c]@n" },
|
|
|
|
|
{ -1, "" }, /* 10 */
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" }, /* 15 */
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" }, /* 20 */
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" }, /* 25 */
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ SECT_EMPTY, " " }, /* 30 */
|
|
|
|
|
{ SECT_STRANGE, "@c[@R?@c]@n" },
|
|
|
|
|
{ SECT_HERE, "@c[@B!@c]@n" },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct map_info_type world_map_info[] =
|
|
|
|
|
{
|
|
|
|
|
{ SECT_INSIDE, "@n." }, /* 0 */
|
|
|
|
|
{ SECT_CITY, "@wC" },
|
|
|
|
|
{ SECT_FIELD, "@g," },
|
|
|
|
|
{ SECT_FOREST, "@gY" },
|
|
|
|
|
{ SECT_HILLS, "@Mm" },
|
|
|
|
|
{ SECT_MOUNTAIN, "@rM" }, /* 5 */
|
|
|
|
|
{ SECT_WATER_SWIM, "@c~" },
|
|
|
|
|
{ SECT_WATER_NOSWIM, "@b=" },
|
|
|
|
|
{ SECT_FLYING, "@C^" },
|
|
|
|
|
{ SECT_UNDERWATER, "@bU" },
|
|
|
|
|
{ -1, "" }, /* 10 */
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" }, /* 15 */
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" }, /* 20 */
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" }, /* 25 */
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ -1, "" },
|
|
|
|
|
{ SECT_EMPTY, " " }, /* 30 */
|
|
|
|
|
{ SECT_STRANGE, "@R?" },
|
|
|
|
|
{ SECT_HERE, "@B!" },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int map[MAX_MAP][MAX_MAP];
|
|
|
|
|
static int offsets[4][2] ={ {-2, 0},{ 0, 2},{ 2, 0},{ 0, -2} };
|
|
|
|
|
static int offsets_worldmap[4][2] ={ {-1, 0},{ 0, 1},{ 1, 0},{ 0, -1} };
|
|
|
|
|
static int door_offsets[6][2] ={ {-1, 0},{ 0, 1},{ 1, 0},{ 0, -1},{ -1, 1},{ 1, 1} };
|
|
|
|
|
static int door_marks[6] = { DOOR_NS, DOOR_EW, DOOR_NS, DOOR_EW, DOOR_UP, DOOR_DOWN };
|
|
|
|
|
static int vdoor_marks[4] = { VDOOR_NS, VDOOR_EW, VDOOR_NS, VDOOR_EW };
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
* End Local (File Scope) Defines and Global Variables
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
* Begin Local (File Scope) Function Prototypes
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
static void MapArea(room_rnum room, struct char_data *ch, int x, int y, int min, int max, sh_int xpos, sh_int ypos, bool worldmap);
|
|
|
|
|
static char *StringMap(int centre, int size);
|
|
|
|
|
static char *WorldMap(int centre, int size, int mapshape, int maptype );
|
|
|
|
|
static char *CompactStringMap(int centre, int size);
|
|
|
|
|
static void perform_map( struct char_data *ch, char *argument, bool worldmap );
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
* End Local (File Scope) Function Prototypes
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool can_see_map(struct char_data *ch) {
|
|
|
|
|
/* Is the map funcionality disabled? */
|
|
|
|
|
if (CONFIG_MAP == MAP_OFF)
|
|
|
|
|
return FALSE;
|
|
|
|
|
else if ((CONFIG_MAP == MAP_IMM_ONLY) && (GET_LEVEL(ch) < LVL_IMMORT))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* MapArea function - create the actual map */
|
|
|
|
|
static void MapArea(room_rnum room, struct char_data *ch, int x, int y, int min, int max, sh_int xpos, sh_int ypos, bool worldmap)
|
|
|
|
|
{
|
|
|
|
|
room_rnum prospect_room;
|
|
|
|
|
struct room_direction_data *pexit;
|
|
|
|
|
int door, ew_size=0, ns_size=0, x_exit_pos=0, y_exit_pos=0;
|
|
|
|
|
sh_int prospect_xpos, prospect_ypos;
|
|
|
|
|
|
|
|
|
|
if (map[x][y] < 0)
|
|
|
|
|
return; /* this is a door */
|
|
|
|
|
|
|
|
|
|
/* marks the room as visited */
|
|
|
|
|
if(room == IN_ROOM(ch))
|
|
|
|
|
map[x][y] = SECT_HERE;
|
|
|
|
|
else
|
|
|
|
|
map[x][y] = SECT(room);
|
|
|
|
|
|
|
|
|
|
if ( (x < min) || ( y < min) || ( x > max ) || ( y > max) ) return;
|
|
|
|
|
|
|
|
|
|
/* Check for exits */
|
|
|
|
|
for ( door = 0; door < MAX_MAP_DIR; door++ ) {
|
|
|
|
|
|
|
|
|
|
if( door < MAX_MAP_FOLLOW &&
|
|
|
|
|
xpos+door_offsets[door][0] >= 0 &&
|
|
|
|
|
xpos+door_offsets[door][0] <= ns_size &&
|
|
|
|
|
ypos+door_offsets[door][1] >= 0 &&
|
|
|
|
|
ypos+door_offsets[door][1] <= ew_size)
|
|
|
|
|
{ /* Virtual exit */
|
|
|
|
|
|
|
|
|
|
map[x+door_offsets[door][0]][y+door_offsets[door][1]] = vdoor_marks[door] ;
|
|
|
|
|
if (map[x+offsets[door][0]][y+offsets[door][1]] == SECT_EMPTY )
|
|
|
|
|
MapArea(room,ch,x + offsets[door][0], y + offsets[door][1], min, max, xpos+door_offsets[door][0], ypos+door_offsets[door][1], worldmap);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-04 21:49:11 +00:00
|
|
|
if ( (pexit = world[room].dir_option[door]) != NULL &&
|
2008-04-14 20:32:21 +00:00
|
|
|
(pexit->to_room > 0 ) && (pexit->to_room != NOWHERE) &&
|
|
|
|
|
(!IS_SET(pexit->exit_info, EX_CLOSED))) { /* A real exit */
|
|
|
|
|
|
|
|
|
|
/* But is the door here... */
|
|
|
|
|
switch (door) {
|
|
|
|
|
case NORTH:
|
|
|
|
|
if(xpos > 0 || ypos!=y_exit_pos) continue;
|
|
|
|
|
break;
|
|
|
|
|
case SOUTH:
|
|
|
|
|
if(xpos < ns_size || ypos!=y_exit_pos) continue;
|
|
|
|
|
break;
|
|
|
|
|
case EAST:
|
|
|
|
|
if(ypos < ew_size || xpos!=x_exit_pos) continue;
|
|
|
|
|
break;
|
|
|
|
|
case WEST:
|
|
|
|
|
if(ypos > 0 || xpos!=x_exit_pos) continue;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if ( (x < min) || ( y < min) || ( x > max ) || ( y > max) ) return;*/
|
|
|
|
|
prospect_room = pexit->to_room;
|
|
|
|
|
|
|
|
|
|
/* one way into area OR maze */
|
|
|
|
|
if ( world[prospect_room].dir_option[rev_dir[door]] &&
|
|
|
|
|
world[prospect_room].dir_option[rev_dir[door]]->to_room != room) {
|
|
|
|
|
map[x][y] = SECT_STRANGE;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!worldmap)
|
|
|
|
|
map[x+door_offsets[door][0]][y+door_offsets[door][1]] = door_marks[door] ;
|
|
|
|
|
|
|
|
|
|
prospect_xpos = prospect_ypos = 0;
|
|
|
|
|
switch (door) {
|
|
|
|
|
case NORTH:
|
|
|
|
|
prospect_xpos = ns_size;
|
|
|
|
|
case SOUTH:
|
|
|
|
|
prospect_ypos = world[prospect_room].dir_option[rev_dir[door]] ? y_exit_pos : ew_size/2;
|
|
|
|
|
break;
|
|
|
|
|
case WEST:
|
|
|
|
|
prospect_ypos = ew_size;
|
|
|
|
|
case EAST:
|
|
|
|
|
prospect_xpos = world[prospect_room].dir_option[rev_dir[door]] ? x_exit_pos : ns_size/2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(worldmap) {
|
|
|
|
|
if ( door < MAX_MAP_FOLLOW && map[x+offsets_worldmap[door][0]][y+offsets_worldmap[door][1]] == SECT_EMPTY )
|
|
|
|
|
MapArea(pexit->to_room,ch,x + offsets_worldmap[door][0], y + offsets_worldmap[door][1], min, max, prospect_xpos, prospect_ypos, worldmap);
|
|
|
|
|
} else {
|
|
|
|
|
if ( door < MAX_MAP_FOLLOW && map[x+offsets[door][0]][y+offsets[door][1]] == SECT_EMPTY )
|
|
|
|
|
MapArea(pexit->to_room,ch,x + offsets[door][0], y + offsets[door][1], min, max, prospect_xpos, prospect_ypos, worldmap);
|
|
|
|
|
}
|
|
|
|
|
} /* end if exit there */
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns a string representation of the map */
|
|
|
|
|
static char *StringMap(int centre, int size)
|
|
|
|
|
{
|
|
|
|
|
static char strmap[MAX_MAP*MAX_MAP*11 + MAX_MAP*2 + 1];
|
|
|
|
|
char *mp = strmap;
|
|
|
|
|
char *tmp;
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
/* every row */
|
|
|
|
|
for (x = centre - CANVAS_HEIGHT/2; x <= centre + CANVAS_HEIGHT/2; x++) {
|
|
|
|
|
/* every column */
|
|
|
|
|
for (y = centre - CANVAS_WIDTH/6; y <= centre + CANVAS_WIDTH/6; y++) {
|
|
|
|
|
if (abs(centre - x)<=size && abs(centre-y)<=size)
|
|
|
|
|
tmp = (map[x][y]<0) ? \
|
|
|
|
|
door_info[NUM_DOOR_TYPES + map[x][y]].disp : \
|
|
|
|
|
map_info[map[x][y]].disp ;
|
|
|
|
|
else
|
|
|
|
|
tmp = map_info[SECT_EMPTY].disp;
|
|
|
|
|
strcpy(mp, tmp);
|
|
|
|
|
mp += strlen(tmp);
|
|
|
|
|
}
|
|
|
|
|
strcpy(mp, "\r\n");
|
|
|
|
|
mp+=2;
|
|
|
|
|
}
|
|
|
|
|
*mp='\0';
|
|
|
|
|
return strmap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *WorldMap(int centre, int size, int mapshape, int maptype )
|
|
|
|
|
{
|
|
|
|
|
static char strmap[MAX_MAP*MAX_MAP*4 + MAX_MAP*2 + 1];
|
|
|
|
|
char *mp = strmap;
|
|
|
|
|
int x, y;
|
|
|
|
|
int xmin, xmax, ymin, ymax;
|
|
|
|
|
|
|
|
|
|
switch(maptype) {
|
|
|
|
|
case MAP_COMPACT:
|
|
|
|
|
xmin = centre - size;
|
|
|
|
|
xmax = centre + size;
|
|
|
|
|
ymin = centre - 2*size;
|
|
|
|
|
ymax = centre + 2*size;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
xmin = centre - CANVAS_HEIGHT/2;
|
|
|
|
|
xmax = centre + CANVAS_HEIGHT/2;
|
|
|
|
|
ymin = centre - CANVAS_WIDTH/2;
|
|
|
|
|
ymax = centre + CANVAS_WIDTH/2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* every row */
|
|
|
|
|
/* for (x = centre - size; x <= centre + size; x++) { */
|
|
|
|
|
for (x = xmin; x <= xmax; x++) {
|
|
|
|
|
/* every column */
|
|
|
|
|
/* for (y = centre - (2*size) ; y <= centre + (2*size) ; y++) { */
|
|
|
|
|
for (y = ymin ; y <= ymax ; y++) {
|
|
|
|
|
|
|
|
|
|
if((mapshape == MAP_RECTANGLE && abs(centre - y) <= size*2 && abs(centre - x) <= size ) ||
|
|
|
|
|
((mapshape == MAP_CIRCLE) && (centre-x)*(centre-x) + (centre-y)*(centre-y)/4 <= (size * size + 1))) {
|
|
|
|
|
strcpy(mp, world_map_info[map[x][y]].disp);
|
|
|
|
|
mp += strlen(world_map_info[map[x][y]].disp);
|
|
|
|
|
} else {
|
|
|
|
|
strcpy(mp++, " ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
strcpy(mp, "@n\r\n");
|
|
|
|
|
mp+=4;
|
|
|
|
|
}
|
|
|
|
|
*mp='\0';
|
|
|
|
|
return strmap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *CompactStringMap(int centre, int size)
|
|
|
|
|
{
|
|
|
|
|
static char strmap[MAX_MAP*MAX_MAP*12 + MAX_MAP*2 + 1];
|
|
|
|
|
char *mp = strmap;
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
/* every row */
|
|
|
|
|
for (x = centre - size; x <= centre + size; x++) {
|
|
|
|
|
/* every column */
|
|
|
|
|
for (y = centre - size; y <= centre + size; y++) {
|
|
|
|
|
strcpy(mp, (map[x][y]<0) ? \
|
|
|
|
|
compact_door_info[NUM_DOOR_TYPES + map[x][y]].disp : \
|
|
|
|
|
map_info[map[x][y]].disp);
|
|
|
|
|
mp += strlen((map[x][y]<0) ? \
|
|
|
|
|
compact_door_info[NUM_DOOR_TYPES + map[x][y]].disp : \
|
|
|
|
|
map_info[map[x][y]].disp);
|
|
|
|
|
}
|
|
|
|
|
strcpy(mp, "\r\n");
|
|
|
|
|
mp+=2;
|
|
|
|
|
}
|
|
|
|
|
*mp='\0';
|
|
|
|
|
return strmap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Display a nicely formatted map with a legend */
|
|
|
|
|
static void perform_map( struct char_data *ch, char *argument, bool worldmap )
|
|
|
|
|
{
|
|
|
|
|
int size = DEFAULT_MAP_SIZE;
|
|
|
|
|
int centre, x, y, min, max;
|
|
|
|
|
char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH], buf1[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH];
|
|
|
|
|
int count = 0;
|
|
|
|
|
int ew_size=0, ns_size=0;
|
|
|
|
|
int mapshape = MAP_CIRCLE;
|
|
|
|
|
|
|
|
|
|
two_arguments( argument, arg1 , arg2 );
|
|
|
|
|
if(*arg1)
|
|
|
|
|
{
|
|
|
|
|
size = atoi(arg1);
|
|
|
|
|
}
|
|
|
|
|
if (*arg2)
|
|
|
|
|
{
|
|
|
|
|
if (is_abbrev(arg2, "normal")) worldmap=FALSE;
|
|
|
|
|
else if (is_abbrev(arg2, "world")) worldmap=TRUE;
|
|
|
|
|
else {
|
|
|
|
|
send_to_char(ch, "Usage: @ymap <distance> [ normal | world ]@n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(size<0) {
|
|
|
|
|
size = -size;
|
|
|
|
|
mapshape = MAP_RECTANGLE;
|
|
|
|
|
}
|
|
|
|
|
size = URANGE(1,size,MAX_MAP_SIZE);
|
|
|
|
|
|
|
|
|
|
centre = MAX_MAP/2;
|
|
|
|
|
|
|
|
|
|
if(worldmap) {
|
|
|
|
|
min = centre - 2*size;
|
|
|
|
|
max = centre + 2*size;
|
|
|
|
|
} else {
|
|
|
|
|
min = centre - size;
|
|
|
|
|
max = centre + size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Blank the map */
|
|
|
|
|
for (x = 0; x < MAX_MAP; ++x)
|
|
|
|
|
for (y = 0; y < MAX_MAP; ++y)
|
|
|
|
|
map[x][y]= (!(y%2) && !worldmap) ? DOOR_NONE : SECT_EMPTY;
|
|
|
|
|
|
|
|
|
|
/* starts the mapping with the centre room */
|
|
|
|
|
MapArea(IN_ROOM(ch), ch, centre, centre, min, max, ns_size/2, ew_size/2, worldmap);
|
|
|
|
|
|
|
|
|
|
/* marks the center, where ch is */
|
|
|
|
|
map[centre][centre] = SECT_HERE;
|
|
|
|
|
|
|
|
|
|
/* Feel free to put your own MUD name or header in here */
|
|
|
|
|
send_to_char(ch, " @Y-@ytbaMUD Map System@Y-@n\r\n"
|
|
|
|
|
"@D .-.__--.,--.__.-.@n\r\n" );
|
|
|
|
|
|
|
|
|
|
count += sprintf(buf + count, "@n@n@n%s Up\\\\", door_info[NUM_DOOR_TYPES + DOOR_UP].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n@n@n%s Down\\\\", door_info[NUM_DOOR_TYPES + DOOR_DOWN].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s You\\\\", map_info[SECT_HERE].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Inside\\\\", map_info[SECT_INSIDE].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s City\\\\", map_info[SECT_CITY].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Field\\\\", map_info[SECT_FIELD].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Forest\\\\", map_info[SECT_FOREST].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Hills\\\\", map_info[SECT_HILLS].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Mountain\\\\", map_info[SECT_MOUNTAIN].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Swim\\\\", map_info[SECT_WATER_SWIM].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Boat\\\\", map_info[SECT_WATER_NOSWIM].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Flying\\\\", map_info[SECT_FLYING].disp);
|
|
|
|
|
count += sprintf(buf + count, "@n%s Underwater\\\\", map_info[SECT_UNDERWATER].disp);
|
|
|
|
|
|
|
|
|
|
strcpy(buf, strfrmt(buf, LEGEND_WIDTH, CANVAS_HEIGHT + 2, FALSE, TRUE, TRUE));
|
|
|
|
|
|
|
|
|
|
/* Start with an empty column */
|
|
|
|
|
strcpy(buf1, strfrmt("",0, CANVAS_HEIGHT + 2, FALSE, FALSE, TRUE));
|
|
|
|
|
|
|
|
|
|
/* Paste the legend */
|
|
|
|
|
strcpy(buf2, strpaste(buf1, buf, "@D | @n"));
|
|
|
|
|
|
|
|
|
|
/* Set up the map */
|
|
|
|
|
memset(buf, ' ', CANVAS_WIDTH);
|
|
|
|
|
count = (CANVAS_WIDTH);
|
|
|
|
|
if(worldmap)
|
|
|
|
|
count += sprintf(buf + count , "\r\n%s", WorldMap(centre, size, mapshape, MAP_NORMAL));
|
|
|
|
|
else
|
|
|
|
|
count += sprintf(buf + count , "\r\n%s", StringMap(centre, size));
|
|
|
|
|
memset(buf + count, ' ', CANVAS_WIDTH);
|
|
|
|
|
strcpy(buf + count + CANVAS_WIDTH, "\r\n");
|
|
|
|
|
/* Paste it on */
|
|
|
|
|
strcpy(buf2, strpaste(buf2, buf, "@D | @n"));
|
|
|
|
|
/* Paste on the right border */
|
|
|
|
|
strcpy(buf2, strpaste(buf2, buf1, " "));
|
|
|
|
|
/* Print it all out */
|
2008-12-01 19:21:36 +00:00
|
|
|
send_to_char(ch, "%s", buf2);
|
2008-04-14 20:32:21 +00:00
|
|
|
|
|
|
|
|
send_to_char(ch, "@D `.-.__--.,-.__.-.-'@n\r\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Display a string with the map beside it */
|
2008-08-03 21:42:02 +00:00
|
|
|
void str_and_map(char *str, struct char_data *ch, room_vnum target_room ) {
|
2008-04-14 20:32:21 +00:00
|
|
|
int size, centre, x, y, min, max, char_size;
|
|
|
|
|
int ew_size=0, ns_size=0;
|
|
|
|
|
bool worldmap;
|
|
|
|
|
|
|
|
|
|
/* Check MUDs map config options - if disabled, just show room decsription */
|
|
|
|
|
if (!can_see_map(ch)) {
|
2008-12-01 19:21:36 +00:00
|
|
|
send_to_char(ch, "%s", strfrmt(str, GET_SCREEN_WIDTH(ch), 1, FALSE, FALSE, FALSE));
|
2008-04-14 20:32:21 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-03 21:42:02 +00:00
|
|
|
worldmap = ROOM_FLAGGED(target_room, ROOM_WORLDMAP) ? TRUE : FALSE ;
|
2008-04-14 20:32:21 +00:00
|
|
|
|
|
|
|
|
if(!PRF_FLAGGED(ch, PRF_AUTOMAP)) {
|
2008-12-01 19:21:36 +00:00
|
|
|
send_to_char(ch, "%s", strfrmt(str, GET_SCREEN_WIDTH(ch), 1, FALSE, FALSE, FALSE));
|
2008-04-14 20:32:21 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size = CONFIG_MINIMAP_SIZE;
|
|
|
|
|
centre = MAX_MAP/2;
|
|
|
|
|
min = centre - 2*size;
|
|
|
|
|
max = centre + 2*size;
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < MAX_MAP; ++x)
|
|
|
|
|
for (y = 0; y < MAX_MAP; ++y)
|
|
|
|
|
map[x][y]= (!(y%2) && !worldmap) ? DOOR_NONE : SECT_EMPTY;
|
|
|
|
|
|
|
|
|
|
/* starts the mapping with the center room */
|
2008-08-03 21:42:02 +00:00
|
|
|
MapArea(target_room, ch, centre, centre, min, max, ns_size/2, ew_size/2, worldmap );
|
2008-04-14 20:32:21 +00:00
|
|
|
map[centre][centre] = SECT_HERE;
|
|
|
|
|
|
|
|
|
|
/* char_size = rooms + doors + padding */
|
|
|
|
|
if(worldmap)
|
|
|
|
|
char_size = size * 4 + 5;
|
|
|
|
|
else
|
|
|
|
|
char_size = 3*(size+1) + (size) + 4;
|
|
|
|
|
|
|
|
|
|
if(worldmap)
|
2008-12-01 19:21:36 +00:00
|
|
|
send_to_char(ch, "%s", strpaste(strfrmt(str, GET_SCREEN_WIDTH(ch) - char_size, size*2 + 1, FALSE, TRUE, TRUE), WorldMap(centre, size, MAP_CIRCLE, MAP_COMPACT), " "));
|
2008-04-14 20:32:21 +00:00
|
|
|
else
|
2008-12-01 19:21:36 +00:00
|
|
|
send_to_char(ch, "%s", strpaste(strfrmt(str, GET_SCREEN_WIDTH(ch) - char_size, size*2 + 1, FALSE, TRUE, TRUE), CompactStringMap(centre, size), " "));
|
2008-04-14 20:32:21 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ACMD(do_map) {
|
|
|
|
|
if (!can_see_map(ch)) {
|
|
|
|
|
send_to_char(ch, "Sorry, the map is disabled!\r\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
perform_map(ch, argument, ROOM_FLAGGED(IN_ROOM(ch), ROOM_WORLDMAP) ? 1 : 0 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|