diff -BbuprN tbamud-3.55/src/Makefile tbamud-3.55+automap/src/Makefile --- tbamud-3.55/src/Makefile 2008-02-05 21:27:51.944422000 +0000 +++ tbamud-3.55+automap/src/Makefile 2008-02-05 20:03:52.928797000 +0000 @@ -26,8 +26,8 @@ LIBS = -lcrypt OBJFILES = act.comm.o act.informative.o act.item.o act.movement.o \ act.offensive.o act.other.o act.social.o act.wizard.o aedit.o \ - ban.o boards.o bsd-snprintf.o castle.o cedit.o class.o comm.o config.o \ - constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o \ + asciimap.o ban.o boards.o bsd-snprintf.o castle.o cedit.o class.o \ + comm.o config.o constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o \ dg_handler.o dg_misc.o dg_mobcmd.o dg_objcmd.o dg_olc.o dg_scripts.o \ dg_triggers.o dg_variables.o dg_wldcmd.o fight.o genmob.o \ genobj.o genolc.o genshp.o genwld.o genzon.o graph.o handler.o hedit.o \ @@ -39,8 +39,8 @@ OBJFILES = act.comm.o act.informative.o CXREF_FILES = act.comm.c act.informative.c act.item.c act.movement.c \ act.offensive.c act.other.c act.social.c act.wizard.c aedit.c \ - ban.c boards.c bsd-snprintf.c castle.c cedit.c class.c comm.c config.c \ - constants.c db.c dg_comm.c dg_db_scripts.c dg_event.c \ + asciimap.c ban.c boards.c bsd-snprintf.c castle.c cedit.c class.c \ + comm.c config.c constants.c db.c dg_comm.c dg_db_scripts.c dg_event.c \ dg_handler.c dg_misc.c dg_mobcmd.c dg_objcmd.c dg_olc.c dg_scripts.c \ dg_triggers.c dg_variables.c dg_wldcmd.c fight.c genmob.c \ genobj.c genolc.c genshp.c genwld.c genzon.c graph.c handler.c hedit.c \ diff -BbuprN tbamud-3.55/src/Makefile.in tbamud-3.55+automap/src/Makefile.in --- tbamud-3.55/src/Makefile.in 2008-01-16 23:21:14.000000000 +0000 +++ tbamud-3.55+automap/src/Makefile.in 2008-02-05 20:00:07.631922000 +0000 @@ -25,8 +25,8 @@ LIBS = @LIBS@ @CRYPTLIB@ @NETLIB@ OBJFILES = act.comm.o act.informative.o act.item.o act.movement.o \ act.offensive.o act.other.o act.social.o act.wizard.o aedit.o \ - ban.o boards.o bsd-snprintf.o castle.o cedit.o class.o comm.o config.o \ - constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o \ + asciimap.o ban.o boards.o bsd-snprintf.o castle.o cedit.o class.o \ + comm.o config.o constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o \ dg_handler.o dg_misc.o dg_mobcmd.o dg_objcmd.o dg_olc.o dg_scripts.o \ dg_triggers.o dg_variables.o dg_wldcmd.o fight.o genmob.o \ genobj.o genolc.o genshp.o genwld.o genzon.o graph.o handler.o hedit.o \ @@ -38,8 +38,8 @@ OBJFILES = act.comm.o act.informative.o CXREF_FILES = act.comm.c act.informative.c act.item.c act.movement.c \ act.offensive.c act.other.c act.social.c act.wizard.c aedit.c \ - ban.c boards.c bsd-snprintf.c castle.c cedit.c class.c comm.c config.c \ - constants.c db.c dg_comm.c dg_db_scripts.c dg_event.c \ + asciimap.c ban.c boards.c bsd-snprintf.c castle.c cedit.c class.c \ + comm.c config.c constants.c db.c dg_comm.c dg_db_scripts.c dg_event.c \ dg_handler.c dg_misc.c dg_mobcmd.c dg_objcmd.c dg_olc.c dg_scripts.c \ dg_triggers.c dg_variables.c dg_wldcmd.c fight.c genmob.c \ genobj.c genolc.c genshp.c genwld.c genzon.c graph.c handler.c hedit.c \ diff -BbuprN tbamud-3.55/src/act.informative.c tbamud-3.55+automap/src/act.informative.c --- tbamud-3.55/src/act.informative.c 2008-01-16 23:28:12.000000000 +0000 +++ tbamud-3.55+automap/src/act.informative.c 2008-02-05 19:58:08.803797000 +0000 @@ -47,6 +47,8 @@ char *title_female(int chclass, int leve struct time_info_data *real_time_passed(time_t t2, time_t t1); int compute_armor_class(struct char_data *ch); int has_mail(long id); +bool can_see_map(struct char_data *ch); +void str_and_map(char *str, struct char_data *ch ); /* local functions */ int sort_commands_helper(const void *a, const void *b); @@ -529,7 +531,16 @@ void look_at_room(struct char_data *ch, if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief || ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) + { + if(!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch)) + { + str_and_map(world[IN_ROOM(ch)].description, ch); + } + else + { send_to_char(ch, "%s", world[IN_ROOM(ch)].description); + } + } /* autoexits */ if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT)) @@ -1860,6 +1871,10 @@ ACMD(do_toggle) {"autoassist", PRF_AUTOASSIST, 0, "Autoassist disabled.\r\n", "Autoassist enabled.\r\n"}, + {"screenwidth", 0, 0, "\n", "\n"}, + {"automap", PRF_AUTOMAP, 0, + "You will no longer see the mini-map.\r\n", + "You will now see a mini-map at the side of room descriptions.\r\n"}, {"\n", 0, -1, "\n", "\n"} /* must be last */ }; @@ -1931,9 +1946,12 @@ ACMD(do_toggle) " AutoSac: %-3s " " AutoAssist: %-3s " - " AFK: %-3s\r\n" + " AutoMap: %-3s " " Pagelength: %-3d " + " Screenwidth: %-3d " + " AFK: %-3s\r\n" + " Color: %s \r\n ", ONOFF(PRF_FLAGGED(ch, PRF_DISPHP)), @@ -1962,9 +1980,12 @@ ACMD(do_toggle) ONOFF(PRF_FLAGGED(ch, PRF_AUTOSAC)), ONOFF(PRF_FLAGGED(ch, PRF_AUTOASSIST)), - ONOFF(PRF_FLAGGED(ch, PRF_AFK)), + ONOFF(PRF_FLAGGED(ch, PRF_AUTOMAP)), GET_PAGE_LENGTH(ch), + GET_SCREEN_WIDTH(ch), + ONOFF(PRF_FLAGGED(ch, PRF_AFK)), + types[COLOR_LEV(ch)]); return; } @@ -2080,6 +2101,33 @@ ACMD(do_toggle) } else send_to_char(ch, "Please specify a number of lines (5 - 255)."); break; + case SCMD_SCREENWIDTH: + if (!*arg2) + send_to_char(ch, "You current screen width is set to %d characters.", GET_SCREEN_WIDTH(ch)); + else if (is_number(arg2)) { + GET_SCREEN_WIDTH(ch) = MIN(MAX(atoi(arg2), 40), 200); + send_to_char(ch, "Okay, your screen width is now set to %d characters.", GET_SCREEN_WIDTH(ch)); + } else + send_to_char(ch, "Please specify a number of characters (40 - 200)."); + break; + case SCMD_AUTOMAP: + if (can_see_map(ch)) { + if (!*arg2) { + TOGGLE_BIT_AR(PRF_FLAGS(ch), tog_messages[toggle].toggle); + result = (PRF_FLAGGED(ch, tog_messages[toggle].toggle)); + } else if (!strcmp(arg2, "on")) { + SET_BIT_AR(PRF_FLAGS(ch), tog_messages[toggle].toggle); + result = 1; + } else if (!strcmp(arg2, "off")) { + REMOVE_BIT_AR(PRF_FLAGS(ch), tog_messages[toggle].toggle); + } else { + send_to_char(ch, "Value for %s must either be 'on' or 'off'.\r\n", tog_messages[toggle].command); + return; + } + } else { + send_to_char(ch, "Sorry, automap is currently disabled.\r\n"); + return; + } default: if (!*arg2) { TOGGLE_BIT_AR(PRF_FLAGS(ch), tog_messages[toggle].toggle); diff -BbuprN tbamud-3.55/src/act.wizard.c tbamud-3.55+automap/src/act.wizard.c --- tbamud-3.55/src/act.wizard.c 2008-01-16 23:28:42.000000000 +0000 +++ tbamud-3.55+automap/src/act.wizard.c 2008-02-05 19:05:52.913172000 +0000 @@ -862,7 +862,9 @@ void do_stat_character(struct char_data GET_GOLD(k), GET_BANK_GOLD(k), GET_GOLD(k) + GET_BANK_GOLD(k)); if (!IS_NPC(k)) - send_to_char(ch, "Questpoints: [%d]\r\n", GET_QUESTPOINTS(k)); + send_to_char(ch, "Questpoints: [%d] Screen %s[%s%d%sx%s%d%s]%s\r\n", GET_QUESTPOINTS(k), + CCCYN(ch, C_NRM), CCYEL(ch, C_NRM), GET_SCREEN_WIDTH(k), CCNRM(ch, C_NRM), + CCYEL(ch, C_NRM), GET_PAGE_LENGTH(k), CCCYN(ch, C_NRM), CCNRM(ch, C_NRM)); send_to_char(ch, "AC: [%d%+d/10], Hitroll: [%2d], Damroll: [%2d], Saving throws: [%d/%d/%d/%d/%d]\r\n", GET_AC(k), dex_app[GET_DEX(k)].defensive, k->points.hitroll, @@ -2744,18 +2746,19 @@ ACMD(do_show) { "practices", LVL_GOD, PC, NUMBER }, /* 40 */ { "quest", LVL_GOD, PC, BINARY }, { "room", LVL_BUILDER, BOTH, NUMBER }, + { "screenwidth", LVL_GOD, PC, NUMBER }, { "sex", LVL_GOD, BOTH, MISC }, - { "showvnums", LVL_BUILDER, PC, BINARY }, - { "siteok", LVL_GOD, PC, BINARY }, /* 45 */ + { "showvnums", LVL_BUILDER, PC, BINARY }, /* 45 */ + { "siteok", LVL_GOD, PC, BINARY }, { "str", LVL_BUILDER, BOTH, NUMBER }, { "stradd", LVL_BUILDER, BOTH, NUMBER }, { "thief", LVL_GOD, PC, BINARY }, - { "thirst", LVL_BUILDER, BOTH, MISC }, - { "title", LVL_GOD, PC, MISC }, /* 50 */ + { "thirst", LVL_BUILDER, BOTH, MISC }, /* 50 */ + { "title", LVL_GOD, PC, MISC }, { "variable", LVL_GRGOD, PC, MISC }, { "weight", LVL_BUILDER, BOTH, NUMBER }, { "wis", LVL_BUILDER, BOTH, NUMBER }, - { "questpoints", LVL_GOD, PC, NUMBER }, + { "questpoints", LVL_GOD, PC, NUMBER }, /* 55 */ { "\n", 0, BOTH, MISC } }; @@ -3074,20 +3077,23 @@ int perform_set(struct char_data *ch, st char_from_room(vict); char_to_room(vict, rnum); break; - case 43: /* sex */ + case 43: /* screenwidth */ + GET_SCREEN_WIDTH(vict) = RANGE(40, 200); + break; + case 44: /* sex */ if ((i = search_block(val_arg, genders, FALSE)) < 0) { send_to_char(ch, "Must be 'male', 'female', or 'neutral'.\r\n"); return (0); } GET_SEX(vict) = i; break; - case 44: /* showvnums */ + case 45: /* showvnums */ SET_OR_REMOVE(PRF_FLAGS(vict), PRF_SHOWVNUMS); break; - case 45: /* siteok */ + case 46: /* siteok */ SET_OR_REMOVE(PLR_FLAGS(vict), PLR_SITEOK); break; - case 46: /* str */ + case 47: /* str */ if (IS_NPC(vict) || GET_LEVEL(vict) >= LVL_GRGOD) RANGE(3, 25); else @@ -3096,16 +3102,16 @@ int perform_set(struct char_data *ch, st vict->real_abils.str_add = 0; affect_total(vict); break; - case 47: /* stradd */ + case 48: /* stradd */ vict->real_abils.str_add = RANGE(0, 100); if (value > 0) vict->real_abils.str = 18; affect_total(vict); break; - case 48: /* thief */ + case 49: /* thief */ SET_OR_REMOVE(PLR_FLAGS(vict), PLR_THIEF); break; - case 49: /* thirst */ + case 50: /* thirst */ if (!str_cmp(val_arg, "off")) { GET_COND(vict, THIRST) = -1; send_to_char(ch, "%s's thirst is now off.\r\n", GET_NAME(vict)); @@ -3119,18 +3125,18 @@ int perform_set(struct char_data *ch, st return (0); } break; - case 50: /* title */ + case 51: /* title */ set_title(vict, val_arg); send_to_char(ch, "%s's title is now: %s\r\n", GET_NAME(vict), GET_TITLE(vict)); break; - case 51: /* variable */ + case 52: /* variable */ return perform_set_dg_var(ch, vict, val_arg); break; - case 52: /* weight */ + case 53: /* weight */ GET_WEIGHT(vict) = value; affect_total(vict); break; - case 53: /* wis */ + case 54: /* wis */ if (IS_NPC(vict) || GET_LEVEL(vict) >= LVL_GRGOD) RANGE(3, 25); else @@ -3138,7 +3144,7 @@ int perform_set(struct char_data *ch, st vict->real_abils.wis = value; affect_total(vict); break; - case 54: /* questpoints */ + case 55: /* questpoints */ GET_QUESTPOINTS(vict) = RANGE(0, 100000000); break; default: diff -BbuprN tbamud-3.55/src/asciimap.c tbamud-3.55+automap/src/asciimap.c --- tbamud-3.55/src/asciimap.c 1970-01-01 00:00:00.000000000 +0000 +++ tbamud-3.55+automap/src/asciimap.c 2008-02-05 20:24:41.069422000 +0000 @@ -0,0 +1,528 @@ +/************************************************************************** +* 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" + +/* 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 + +// char *strfrmt(char *str, int w, int h, int justify, int hpad, int vpad); +// char *strpaste(char *str1, char *str2, char *joiner); + +extern struct room_data *world; +int add_to_save_list(zone_vnum zone, int type); +int can_edit_zone(struct char_data *ch, int number); + +struct map_info_type +{ + int sector_type; + char disp[20]; +}; + +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, " | " } +}; + +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 */ +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" }, +}; + +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!" }, +}; + + +int map[MAX_MAP][MAX_MAP]; +int offsets[4][2] ={ {-2, 0},{ 0, 2},{ 2, 0},{ 0, -2} }; +int offsets_worldmap[4][2] ={ {-1, 0},{ 0, 1},{ 1, 0},{ 0, -1} }; +int door_offsets[6][2] ={ {-1, 0},{ 0, 1},{ 1, 0},{ 0, -1},{ -1, 1},{ 1, 1} }; +int door_marks[6] = { DOOR_NS, DOOR_EW, DOOR_NS, DOOR_EW, DOOR_UP, DOOR_DOWN }; +int vdoor_marks[4] = { VDOOR_NS, VDOOR_EW, VDOOR_NS, VDOOR_EW }; + +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 */ +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; + } + + if ( (pexit = world[room].dir_option[door]) > 0 && + (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 */ +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; +} + +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; +} + +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 */ +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 [ 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 */ + send_to_char(ch, buf2); + + send_to_char(ch, "@D `.-.__--.,-.__.-.-'@n\r\n"); + return; +} + +/* Display a string with the map beside it */ +void str_and_map(char *str, struct char_data *ch ) { + 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)) { + send_to_char(ch, strfrmt(str, GET_SCREEN_WIDTH(ch), 1, FALSE, FALSE, FALSE)); + return; + } + + worldmap = ROOM_FLAGGED(IN_ROOM(ch), ROOM_WORLDMAP) ? TRUE : FALSE ; + + if(!PRF_FLAGGED(ch, PRF_AUTOMAP)) { + send_to_char(ch, strfrmt(str, GET_SCREEN_WIDTH(ch), 1, FALSE, FALSE, FALSE)); + 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 */ + MapArea(IN_ROOM(ch), ch, centre, centre, min, max, ns_size/2, ew_size/2, worldmap ); + 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) + send_to_char(ch, strpaste(strfrmt(str, GET_SCREEN_WIDTH(ch) - char_size, size*2 + 1, FALSE, TRUE, TRUE), WorldMap(centre, size, MAP_CIRCLE, MAP_COMPACT), " ")); + else + send_to_char(ch, strpaste(strfrmt(str, GET_SCREEN_WIDTH(ch) - char_size, size*2 + 1, FALSE, TRUE, TRUE), CompactStringMap(centre, size), " ")); + +} + +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 ); +} + + diff -BbuprN tbamud-3.55/src/cedit.c tbamud-3.55+automap/src/cedit.c --- tbamud-3.55/src/cedit.c 2008-01-16 23:21:14.000000000 +0000 +++ tbamud-3.55+automap/src/cedit.c 2008-02-05 20:19:50.569422000 +0000 @@ -103,6 +103,9 @@ void cedit_setup(struct descriptor_data OLC_CONFIG(d)->play.track_through_doors = CONFIG_TRACK_T_DOORS; OLC_CONFIG(d)->play.no_mort_to_immort = CONFIG_NO_MORT_TO_IMMORT; OLC_CONFIG(d)->play.disp_closed_doors = CONFIG_DISP_CLOSED_DOORS; + OLC_CONFIG(d)->play.map_option = CONFIG_MAP; + OLC_CONFIG(d)->play.map_size = CONFIG_MAP_SIZE; + OLC_CONFIG(d)->play.minimap_size = CONFIG_MINIMAP_SIZE; /* Crash Saves */ OLC_CONFIG(d)->csd.free_rent = CONFIG_FREE_RENT; @@ -196,6 +199,9 @@ void cedit_save_internally(struct descri CONFIG_TRACK_T_DOORS = OLC_CONFIG(d)->play.track_through_doors; CONFIG_NO_MORT_TO_IMMORT = OLC_CONFIG(d)->play.no_mort_to_immort; CONFIG_DISP_CLOSED_DOORS = OLC_CONFIG(d)->play.disp_closed_doors; + CONFIG_MAP = OLC_CONFIG(d)->play.map_option; + CONFIG_MAP_SIZE = OLC_CONFIG(d)->play.map_size; + CONFIG_MINIMAP_SIZE = OLC_CONFIG(d)->play.minimap_size; /* Crash Saves */ CONFIG_FREE_RENT = OLC_CONFIG(d)->csd.free_rent; @@ -354,6 +360,12 @@ int save_config( IDXTYPE nowhere ) "no_mort_to_immort = %d\n\n", CONFIG_NO_MORT_TO_IMMORT); fprintf(fl, "* Should closed doors be shown on autoexit / exit?\n" "disp_closed_doors = %d\n\n", CONFIG_DISP_CLOSED_DOORS); + fprintf(fl, "* Who can use the map functions? 0=off, 1=on, 2=imm_only\n" + "map_option = %d\n\n", CONFIG_MAP); + fprintf(fl, "* Default size of map shown by 'map' command\n" + "default_map_size = %d\n\n", CONFIG_MAP_SIZE); + fprintf(fl, "* Default minimap size shown to the right of room descriptions\n" + "default_minimap_size = %d\n\n", CONFIG_MINIMAP_SIZE); strcpy(buf, CONFIG_OK); strip_cr(buf); @@ -553,9 +565,12 @@ void cedit_disp_menu(struct descriptor_d void cedit_disp_game_play_options(struct descriptor_data *d) { + int m_opt; get_char_colors(d->character); clear_screen(d); + m_opt = OLC_CONFIG(d)->play.map_option; + write_to_output(d, "\r\n\r\n" "%sA%s) Player Killing Allowed : %s%s\r\n" "%sB%s) Player Thieving Allowed : %s%s\r\n" @@ -577,6 +592,9 @@ void cedit_disp_game_play_options(struct "%s1%s) OK Message Text : %s%s" "%s2%s) NOPERSON Message Text : %s%s" "%s3%s) NOEFFECT Message Text : %s%s" + "%s4%s) Map/Automap Option : %s%s\r\n" + "%s5%s) Default map size : %s%d\r\n" + "%s6%s) Default minimap size : %s%d\r\n" "%sQ%s) Exit To The Main Menu\r\n" "Enter your choice : ", grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pk_allowed), @@ -601,6 +619,9 @@ void cedit_disp_game_play_options(struct grn, nrm, cyn, OLC_CONFIG(d)->play.OK, grn, nrm, cyn, OLC_CONFIG(d)->play.NOPERSON, grn, nrm, cyn, OLC_CONFIG(d)->play.NOEFFECT, + grn, nrm, cyn, m_opt == 0 ? "Off" : (m_opt == 1 ? "On" : (m_opt == 2 ? "Imm-Only" : "Invalid!")), + grn, nrm, cyn, OLC_CONFIG(d)->play.map_size, + grn, nrm, cyn, OLC_CONFIG(d)->play.minimap_size, grn, nrm ); @@ -910,6 +931,24 @@ void cedit_parse(struct descriptor_data OLC_MODE(d) = CEDIT_NOEFFECT; return; + case '4': + write_to_output(d, "1) Disable maps\r\n"); + write_to_output(d, "2) Enable Maps\r\n"); + write_to_output(d, "3) Maps for Immortals only\r\n"); + write_to_output(d, "Enter choice: "); + OLC_MODE(d) = CEDIT_MAP_OPTION; + return; + + case '5': + write_to_output(d, "Enter default map size (1-12) : "); + OLC_MODE(d) = CEDIT_MAP_SIZE; + return; + + case '6': + write_to_output(d, "Enter default mini-map size (1-12) : "); + OLC_MODE(d) = CEDIT_MINIMAP_SIZE; + return; + case 'q': case 'Q': cedit_disp_menu(d); @@ -1522,6 +1561,40 @@ void cedit_parse(struct descriptor_data } break; + case CEDIT_MAP_OPTION: + if (!*arg) { + write_to_output(d, + "That is an invalid choice!\r\n" + "Select 1, 2 or 3 (0 to cancel) :"); + } else { + if ((atoi(arg) >= 1) && (atoi(arg) <= 3)) + OLC_CONFIG(d)->play.map_option = (atoi(arg) - 1); + cedit_disp_game_play_options(d); + } + break; + + case CEDIT_MAP_SIZE: + if (!*arg) { + /* User just pressed return - restore to default */ + OLC_CONFIG(d)->play.map_size = 6; + cedit_disp_game_play_options(d); + } else { + OLC_CONFIG(d)->play.map_size = MIN(MAX((atoi(arg)), 1), 12); + cedit_disp_game_play_options(d); + } + break; + + case CEDIT_MINIMAP_SIZE: + if (!*arg) { + /* User just pressed return - restore to default */ + OLC_CONFIG(d)->play.minimap_size = 2; + cedit_disp_game_play_options(d); + } else { + OLC_CONFIG(d)->play.minimap_size = MIN(MAX((atoi(arg)), 1), 12); + cedit_disp_game_play_options(d); + } + break; + default: /* We should never get here, but just in case... */ cleanup_olc(d, CLEANUP_CONFIG); mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: cedit_parse(): Reached default case!"); diff -BbuprN tbamud-3.55/src/config.c tbamud-3.55+automap/src/config.c --- tbamud-3.55/src/config.c 2008-01-16 23:21:14.000000000 +0000 +++ tbamud-3.55+automap/src/config.c 2008-02-05 15:00:09.663172000 +0000 @@ -302,3 +302,9 @@ int min_wizlist_lev = LVL_GOD; /* To mimic stock behavior set to NO. To allow mortals to see doors in exits * set to YES. */ int display_closed_doors = YES; + +/* Automap and map options */ +/* Default is to have automap and map command enabled for all players and immortals */ +int map_option = MAP_ON; +int default_map_size = 6; +int default_minimap_size = 2; diff -BbuprN tbamud-3.55/src/constants.c tbamud-3.55+automap/src/constants.c --- tbamud-3.55/src/constants.c 2008-01-16 23:21:16.000000000 +0000 +++ tbamud-3.55+automap/src/constants.c 2008-02-05 22:12:26.819422000 +0000 @@ -50,6 +50,7 @@ const char *room_bits[] = { "ATRIUM", "OLC", "*", /* BFS MARK */ + "WORLDMAP", "\n" }; @@ -184,6 +185,7 @@ const char *preference_bits[] = { "AUTOSPLIT", "AUTOSAC", "AUTOASSIST", + "AUTOMAP", "\n" }; diff -BbuprN tbamud-3.55/src/db.c tbamud-3.55+automap/src/db.c --- tbamud-3.55/src/db.c 2008-01-16 23:21:14.000000000 +0000 +++ tbamud-3.55+automap/src/db.c 2008-02-05 18:50:11.538172000 +0000 @@ -3044,6 +3044,7 @@ void init_char(struct char_data *ch) GET_COND(ch, i) = (GET_LEVEL(ch) == LVL_IMPL ? -1 : 24); GET_LOADROOM(ch) = NOWHERE; + GET_SCREEN_WIDTH(ch) = PAGE_WIDTH; } /* returns the real number of the room with given virtual number */ @@ -3340,6 +3341,9 @@ extern int min_wizlist_lev; extern const char *OK; extern const char *NOPERSON; extern const char *NOEFFECT; +extern int map_option; +extern int default_map_size; +extern int default_minimap_size; void load_default_config( void ) { @@ -3366,6 +3370,9 @@ void load_default_config( void ) CONFIG_TRACK_T_DOORS = track_through_doors; CONFIG_NO_MORT_TO_IMMORT = no_mort_to_immort; CONFIG_DISP_CLOSED_DOORS = display_closed_doors; + CONFIG_MAP = map_option; + CONFIG_MAP_SIZE = default_map_size; + CONFIG_MINIMAP_SIZE = default_minimap_size; /* Rent / crashsave options. */ CONFIG_FREE_RENT = free_rent; @@ -3488,6 +3495,10 @@ void load_config( void ) CONFIG_DFLT_IP = NULL; } else if (!str_cmp(tag, "dflt_port")) CONFIG_DFLT_PORT = num; + else if (!str_cmp(tag, "default_map_size")) + CONFIG_MAP_SIZE = num; + else if (!str_cmp(tag, "default_minimap_size")) + CONFIG_MINIMAP_SIZE = num; break; case 'f': @@ -3558,6 +3569,8 @@ void load_config( void ) CONFIG_MIN_WIZLIST_LEV = num; else if (!str_cmp(tag, "mortal_start_room")) CONFIG_MORTAL_START = num; + else if (!str_cmp(tag, "map_option")) + CONFIG_MAP = num; break; case 'n': diff -BbuprN tbamud-3.55/src/interpreter.c tbamud-3.55+automap/src/interpreter.c --- tbamud-3.55/src/interpreter.c 2008-01-16 23:27:40.000000000 +0000 +++ tbamud-3.55+automap/src/interpreter.c 2008-02-05 19:56:41.522547000 +0000 @@ -131,6 +131,7 @@ ACMD(do_levels); ACMD(do_links); ACMD(do_load); ACMD(do_look); +ACMD(do_map); ACMD(do_masound); ACMD(do_mat); ACMD(do_mdamage); @@ -360,6 +361,7 @@ cpp_extern const struct command_info cmd { "motd" , "motd" , POS_DEAD , do_gen_ps , 0, SCMD_MOTD }, { "mail" , "mail" , POS_STANDING, do_not_here , 1, 0 }, + { "map" , "map" , POS_STANDING, do_map , 1, 0 }, { "medit" , "med" , POS_DEAD , do_oasis_medit, LVL_BUILDER, 0 }, { "mlist" , "mlist" , POS_DEAD , do_oasis_list , LVL_BUILDER, SCMD_OASIS_MLIST }, { "mcopy" , "mcopy" , POS_DEAD , do_oasis_copy, LVL_GOD, CON_MEDIT }, diff -BbuprN tbamud-3.55/src/interpreter.h tbamud-3.55+automap/src/interpreter.h --- tbamud-3.55/src/interpreter.h 2008-01-16 23:21:16.000000000 +0000 +++ tbamud-3.55+automap/src/interpreter.h 2008-02-05 19:45:47.225672000 +0000 @@ -121,6 +121,13 @@ struct alias_data { #define SCMD_SYSLOG 21 #define SCMD_WIMPY 22 #define SCMD_PAGELENGTH 23 +#define SCMD_AUTOLOOT 24 +#define SCMD_AUTOGOLD 25 +#define SCMD_AUTOSPLIT 26 +#define SCMD_AUTOSAC 27 +#define SCMD_AUTOASSIST 28 +#define SCMD_SCREENWIDTH 29 +#define SCMD_AUTOMAP 30 /* do_wizutil */ #define SCMD_REROLL 0 diff -BbuprN tbamud-3.55/src/oasis.h tbamud-3.55+automap/src/oasis.h --- tbamud-3.55/src/oasis.h 2008-01-16 23:21:16.000000000 +0000 +++ tbamud-3.55+automap/src/oasis.h 2008-02-05 20:05:30.881922000 +0000 @@ -17,7 +17,7 @@ /* Macros, defines, structs and globals for the OLC suite. You will need to adjust these numbers if you ever add more. */ -#define NUM_ROOM_FLAGS 16 +#define NUM_ROOM_FLAGS 17 #define NUM_ROOM_SECTORS 10 #define NUM_MOB_FLAGS 18 @@ -355,6 +355,9 @@ extern const char *nrm, *grn, *cyn, *yel #define CEDIT_NAMESERVER_IS_SLOW 51 #define CEDIT_USE_AUTOWIZ 52 #define CEDIT_MIN_WIZLIST_LEV 53 +#define CEDIT_MAP_OPTION 54 +#define CEDIT_MAP_SIZE 55 +#define CEDIT_MINIMAP_SIZE 56 /* Hedit Submodes of connectedness. */ #define HEDIT_CONFIRM_SAVESTRING 0 diff -BbuprN tbamud-3.55/src/pfdefaults.h tbamud-3.55+automap/src/pfdefaults.h --- tbamud-3.55/src/pfdefaults.h 2008-01-16 23:21:16.000000000 +0000 +++ tbamud-3.55+automap/src/pfdefaults.h 2008-02-05 18:01:18.991297000 +0000 @@ -50,6 +50,7 @@ #define PFDEF_DRUNK 0 #define PFDEF_OLC NOWHERE #define PFDEF_PAGELENGTH 22 +#define PFDEF_SCREENWIDTH 80 #define PFDEF_QUESTPOINTS 0 #endif diff -BbuprN tbamud-3.55/src/players.c tbamud-3.55+automap/src/players.c --- tbamud-3.55/src/players.c 2008-01-16 23:21:14.000000000 +0000 +++ tbamud-3.55+automap/src/players.c 2008-02-05 18:30:24.413172000 +0000 @@ -260,6 +260,7 @@ int load_char(const char *name, struct c GET_MAX_MOVE(ch) = PFDEF_MAXMOVE; GET_OLC_ZONE(ch) = PFDEF_OLC; GET_PAGE_LENGTH(ch) = PFDEF_PAGELENGTH; + GET_SCREEN_WIDTH(ch) = PFDEF_SCREENWIDTH; GET_ALIASES(ch) = NULL; SITTING(ch) = NULL; NEXT_SITTING(ch) = NULL; @@ -395,6 +396,7 @@ int load_char(const char *name, struct c case 'S': if (!strcmp(tag, "Sex ")) GET_SEX(ch) = atoi(line); + else if (!strcmp(tag, "ScrW")) GET_SCREEN_WIDTH(ch) = atoi(line); else if (!strcmp(tag, "Skil")) load_skills(fl, ch); else if (!strcmp(tag, "Str ")) load_HMVS(ch, line, LOAD_STRENGTH); break; @@ -598,6 +600,7 @@ void save_char(struct char_data * ch) if (GET_DAMROLL(ch) != PFDEF_DAMROLL) fprintf(fl, "Drol: %d\n", GET_DAMROLL(ch)); if (GET_OLC_ZONE(ch) != PFDEF_OLC) fprintf(fl, "Olc : %d\n", GET_OLC_ZONE(ch)); if (GET_PAGE_LENGTH(ch) != PFDEF_PAGELENGTH) fprintf(fl, "Page: %d\n", GET_PAGE_LENGTH(ch)); + if (GET_SCREEN_WIDTH(ch) != PFDEF_SCREENWIDTH) fprintf(fl, "ScrW: %d\n", GET_SCREEN_WIDTH(ch)); if (GET_QUESTPOINTS(ch) != PFDEF_QUESTPOINTS) fprintf(fl, "Qstp: %d\n", GET_QUESTPOINTS(ch)); /* Save skills */ diff -BbuprN tbamud-3.55/src/structs.h tbamud-3.55+automap/src/structs.h --- tbamud-3.55/src/structs.h 2008-01-16 23:21:16.000000000 +0000 +++ tbamud-3.55+automap/src/structs.h 2008-02-05 20:05:12.647547000 +0000 @@ -69,6 +69,7 @@ #define ROOM_ATRIUM 13 /* (R) The door to a house */ #define ROOM_OLC 14 /* (R) Modifyable/!compress */ #define ROOM_BFS_MARK 15 /* (R) breath-first srch mrk */ +#define ROOM_WORLDMAP 16 /* World-map style maps here */ /* Exit info: used in room_data.dir_option.exit_info */ #define EX_ISDOOR (1 << 0) /* Exit is a door */ @@ -208,7 +209,8 @@ #define PRF_AUTOSPLIT 28 /* Split gold with group */ #define PRF_AUTOSAC 29 /* Sacrifice a corpse */ #define PRF_AUTOASSIST 30 /* Auto-assist toggle */ -#define NUM_PRF_FLAGS 31 +#define PRF_AUTOMAP 31 /* Show map at the side of room descs */ +#define NUM_PRF_FLAGS 32 /* Affect bits: used in char_data.char_specials.saved.affected_by */ /* WARNING: In the world files, NEVER set the bits marked "R" ("Reserved") */ @@ -456,6 +458,11 @@ #define NUM_OF_DIRS 6 /* number of directions in a room (nsewud) */ #define MAGIC_NUMBER (0x06) /* Arbitrary number that won't be in a string */ +/* Map options (settable in cedit) */ +#define MAP_OFF 0 +#define MAP_ON 1 +#define MAP_IMM_ONLY 2 + /* OPT_USEC determines how many commands will be processed by the MUD per * second and how frequently it does socket I/O. A low setting will cause * actions to be executed more frequently but will increase overhead due to @@ -772,6 +779,7 @@ struct player_special_data_saved { sbyte conditions[3]; /* Drunk, hunger, thirst */ struct txt_block *comm_hist[NUM_HIST]; /* Player's comms history */ ubyte page_length; /* How long a players page is */ + ubyte screen_width; /* How wide a players page is */ int spells_to_learn; /* How many spells you can learn */ int olc_zone; /* A players olc access */ int questpoints; /* A players questpoints earned */ @@ -1047,6 +1055,9 @@ struct game_data { int track_through_doors;/* Track through doors while closed? */ int no_mort_to_immort; /* Prevent mortals leveling to imms? */ int disp_closed_doors; /* Display closed doors in autoexit? */ + int map_option; /* MAP_ON, MAP_OFF or MAP_IMM_ONLY */ + int map_size; /* Default size for map command */ + int minimap_size; /* Default size for mini-map (automap) */ char *OK; /* When player receives 'Okay.' text. */ char *NOPERSON; /* 'No one by that name here.' */ diff -BbuprN tbamud-3.55/src/utils.c tbamud-3.55+automap/src/utils.c --- tbamud-3.55/src/utils.c 2008-01-16 23:21:14.000000000 +0000 +++ tbamud-3.55+automap/src/utils.c 2008-02-05 20:07:40.569422000 +0000 @@ -735,3 +735,170 @@ void char_from_furniture(struct char_dat return; } + +/* + strfrmt (String Format) function + Used by automap/map system + Re-formats a string to fit within a particular size box. + Recognises @ color codes, and if a line ends in one color, the + next line will start with the same color. + Ends every line with @n to prevent color bleeds. +*/ +char *strfrmt(char *str, int w, int h, int justify, int hpad, int vpad) +{ + static char ret[MAX_STRING_LENGTH]; + char line[MAX_INPUT_LENGTH]; + char *sp = str; + char *lp = line; + char *rp = ret; + char *wp; + int wlen = 0, llen = 0, lcount = 0; + char last_color='n'; + bool new_line_started = FALSE; + + memset(line, '\0', MAX_INPUT_LENGTH); + /* Nomalize spaces and newlines */ + /* Split into lines, including convert \\ into \r\n */ + while(*sp) { + /* eat leading space */ + while(*sp && isspace(*sp)) sp++; + /* word begins */ + wp = sp; + wlen = 0; + while(*sp) { /* Find the end of the word */ + if(isspace(*sp)) break; + if(*sp=='\\' && sp[1] && sp[1]=='\\') { + if(sp!=wp) + break; /* Finish dealing with the current word */ + sp += 2; /* Eat the marker and any trailing space */ + while(*sp && isspace(*sp)) sp++; + wp = sp; + /* Start a new line */ + if(hpad) + for(; llen < w; llen++) + *lp++ = ' '; + *lp++ = '\r'; + *lp++ = '\n'; + *lp++ = '\0'; + rp += sprintf(rp, "%s", line); + llen = 0; + lcount++; + lp = line; + } else if (*sp=='`'||*sp=='$'||*sp=='#'||*sp=='@') { + if (sp[1] && (sp[1]==*sp)) + wlen++; /* One printable char here */ + if (*sp=='@' && (sp[1]!=*sp)) /* Color code, not @@ */ + last_color = sp[1]; + sp += 2; /* Eat the whole code regardless */ + } else { + wlen++; + sp++; + } + } + if(llen + wlen + (lp==line ? 0 : 1) > w) { + /* Start a new line */ + if(hpad) + for(; llen < w; llen++) + *lp++ = ' '; + *lp++ = '@'; /* 'normal' color */ + *lp++ = 'n'; + *lp++ = '\r'; /* New line */ + *lp++ = '\n'; + *lp++ = '\0'; + sprintf(rp, "%s", line); + rp += strlen(line); + llen = 0; + lcount++; + lp = line; + if (last_color != 'n') { + *lp++ = '@'; /* restore previous color */ + *lp++ = last_color; + new_line_started = TRUE; + } + } + /* add word to line */ + if (lp!=line && new_line_started!=TRUE) { + *lp++ = ' '; + llen++; + } + new_line_started = FALSE; + llen += wlen ; + for( ; wp!=sp ; *lp++ = *wp++); + } + /* Copy over the last line */ + if(lp!=line) { + if(hpad) + for(; llen < w; llen++) + *lp++ = ' '; + *lp++ = '\r'; + *lp++ = '\n'; + *lp++ = '\0'; + sprintf(rp, "%s", line); + rp += strlen(line); + lcount++; + } + if(vpad) { + while(lcount < h) { + if(hpad) { + memset(rp, ' ', w); + rp += w; + } + *rp++ = '\r'; + *rp++ = '\n'; + lcount++; + } + *rp = '\0'; + } + return ret; +} + +/* + strpaste (String Paste) function + Takes two long strings (multiple lines) and joins them side-by-side. + Used by the automap/map system +*/ +char *strpaste(char *str1, char *str2, char *joiner) +{ + static char ret[MAX_STRING_LENGTH+1]; + char *sp1 = str1; + char *sp2 = str2; + char *rp = ret; + int jlen = strlen(joiner); + + while((rp - ret) < MAX_STRING_LENGTH && (*sp1 || *sp2)) { + /* Copy line from str1 */ + while((rp - ret) < MAX_STRING_LENGTH && *sp1 && !ISNEWL(*sp1)) + *rp++ = *sp1++; + /* Eat the newline */ + if(*sp1) { + if(sp1[1] && sp1[1]!=sp1[0] && ISNEWL(sp1[1])) + sp1++; + sp1++; + } + + /* Add the joiner */ + if((rp - ret) + jlen >= MAX_STRING_LENGTH) + break; + strcpy(rp, joiner); + rp += jlen; + + /* Copy line from str2 */ + while((rp - ret) < MAX_STRING_LENGTH && *sp2 && !ISNEWL(*sp2)) + *rp++ = *sp2++; + /* Eat the newline */ + if(*sp2) { + if(sp2[1] && sp2[1]!=sp2[0] && ISNEWL(sp2[1])) + sp2++; + sp2++; + } + + /* Add the newline */ + if((rp - ret) + 2 >= MAX_STRING_LENGTH) + break; + *rp++ = '\r'; + *rp++ = '\n'; + } + /* Close off the string */ + *rp = '\0'; + return ret; +} diff -BbuprN tbamud-3.55/src/utils.h tbamud-3.55+automap/src/utils.h --- tbamud-3.55/src/utils.h 2008-01-16 23:21:14.000000000 +0000 +++ tbamud-3.55+automap/src/utils.h 2008-02-05 20:12:11.928797000 +0000 @@ -36,6 +36,8 @@ void core_dump_real(const char *who, int int count_color_chars(char *string); int room_is_dark(room_rnum room); int levenshtein_distance(char *s1, char *s2); +char *strfrmt(char *str, int w, int h, int justify, int hpad, int vpad); +char *strpaste(char *str1, char *str2, char *joiner); #define core_dump() core_dump_real(__FILE__, __LINE__) @@ -131,6 +133,10 @@ void char_from_furniture(struct char_dat #define SECS_PER_REAL_DAY (24*SECS_PER_REAL_HOUR) #define SECS_PER_REAL_YEAR (365*SECS_PER_REAL_DAY) +/* integer utils */ + +#define URANGE(a, b, c) ((b) < (a) ? (a) : ((b) > (c) ? (c) : (b))) + /* string utils */ #define YESNO(a) ((a) ? "YES" : "NO") #define ONOFF(a) ((a) ? "ON" : "OFF") @@ -316,6 +322,7 @@ void char_from_furniture(struct char_dat #define GET_HOST(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->host)) #define GET_HISTORY(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.comm_hist[i])) #define GET_PAGE_LENGTH(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.page_length)) +#define GET_SCREEN_WIDTH(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.screen_width)) #define GET_QUESTPOINTS(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.questpoints)) #define GET_SKILL(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.skills[i])) @@ -549,6 +556,11 @@ void char_from_furniture(struct char_dat #define CONFIG_NOEFFECT config_info.play.NOEFFECT #define CONFIG_DISP_CLOSED_DOORS config_info.play.disp_closed_doors +/* Map/Automap options */ +#define CONFIG_MAP config_info.play.map_option +#define CONFIG_MAP_SIZE config_info.play.map_size +#define CONFIG_MINIMAP_SIZE config_info.play.minimap_size + /* Crash Saves */ #define CONFIG_FREE_RENT config_info.csd.free_rent #define CONFIG_MAX_OBJ_SAVE config_info.csd.max_obj_save