Dot-language maps

From: Henrik Stuart (hstuart@geocities.com)
Date: 10/23/01


Hey all,

   After a long day of classical algebra the wisest thing you can do
   is sit down and do your homework... therefore I coded instead. :)
   Anyway, joke aside... I've written this small thing that will
   output your zones to the dot graph-language format (which is
   compiled by the dot tool at www.graphviz.org, which is a truly
   awesome tool). Now, some of you might argue that it doesn't look
   much like a traditional map, and that it doesn't, but still it
   gives a nice overview of the zone.
   The current incarnation of the code is fairly simplistic and only
   outputs the core-map, interesting additions are easy to think up
   (for instance colouring death-trap rooms red or the like).
   I chose to insert the code directly into the mud instead of make it
   a separate program only for the reason I wouldn't have to parse the
   world files - the other solution is, of course, a lot nicer, but
   this leaves it open for builders to call the function and get a
   nice jpeg map of their zone when they need it. :o)

   Anyway, enough talk, here's the code, enjoy it or throw it away.

   (And I know a few of the lines in the code are over 80 chars wide,
   and if you're annoyed by that, don't say so already).

<--- SNIP HERE --->
#include "conf.h"
#include "sysdep.h"

#include "structs.h"
#include "utils.h"
#include "db.h"
#include "interpreter.h"

extern int real_zone(int number);
extern int top_of_world;
extern struct room_data* world;
extern struct zone_data* zone_table;
extern int rev_dir[];
extern int top_of_zone_table;

extern void send_to_char(char *messg, struct char_data *ch);

const char* abbrev_dirs[] = {
        "n",
        "e",
        "s",
        "w",
        "u",
        "d",
        "ne",
        "se",
        "nw",
        "sw",
        "\n"
};

void dump_zone(int vnum, struct char_data* ch) {
        int i = 0, j = 0;
        FILE* fp = 0;
        int zone = real_zone(vnum);
        int tele = -1;

        if (zone < 0) {
                send_to_char("Invalid zone - aborting dump.\r\n", ch);
                return;
        }

        sprintf(buf2, "%d.dot", vnum);
        fp = fopen(buf2, "w");
        fprintf(fp, "digraph \"%s\" {\r\n", zone_table[zone].name ? zone_table[zone].name : "zone");
        fprintf(fp, "node [fontsize=\"8\"];");
        fprintf(fp, "edge [fontsize=\"8\"];");

        for (i = 0; i < top_of_world; i++) {
                if ((world[i].number / 100) != vnum)
                        continue;

                for (j = 0; j < NUM_OF_DIRS; j++) {
                        int both = 0;
                        int to = 0;
                        int outside = 0;

                        if (world[i].dir_option[j] == NULL)
                                continue;

                        to = world[i].dir_option[j]->to_room;
                        if (to == NOWHERE)
                                continue;

                        if (world[to].zone != vnum)
                                outside = 0;

                        if (world[to].dir_option[rev_dir[j]] && world[to].dir_option[rev_dir[j]]->to_room == i)
                                if (to > i)
                                        both = 1;
                                else
                                        continue;


                        fprintf(fp, "\"%s (%d)\" -> \"%s (%d)\"", world[i].name, world[i].number, world[to].name, world[to].number);

                        if (both && outside) {
                                fprintf(fp, "[dir=\"both\", color=\".7 .6 .5\"]\r\n");
                        } else if (both) {
                                fprintf(fp, "[dir=\"both\"]\r\n");
                        } else if (outside) {
                                fprintf(fp, "[label=\"%s\", color=\".7 .6 .5\"]\r\n", abbrev_dirs[j]);
                        } else {
                                fprintf(fp, "[label=\"%s\"]\r\n", abbrev_dirs[j]);
                        }

                }
        }

        fprintf(fp, "}\r\n");

        fclose(fp);
}

ACMD(do_dumpzone) {
        int num;

        one_argument(argument, buf);

        if (!buf || !*buf) {
                send_to_char("What zone do you wish to dump to a dot-file?\r\n", ch);
                return;
        }

        num = atoi(buf);

        dump_zone(num, ch);
}

ACMD(do_dumpall) {
        int i;

        for (i = 0; i < top_of_zone_table; i++) {
                dump_zone(zone_table[i].number, ch);
        }
}
<--- SNIP HERE --->

   Remember to add the ACMD's to your interpreter.c command list so
   you can actually call them.

   Feel free to mail me with suggestions. And no, you cannot reorder
   the graphics to be more map-like using the dot-tool. It uses a
   quite cool technique for creating equally weighted graphs (or so it
   claims), so it's not meant for actual maps, but it's nice for
   graphs and a map is kind of a graph so I chose to use that instead
   of writing the graphics program as well. :o)

--
Yours truly,
 Henrik Stuart (http://www.unprompted.com/hstuart/)

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/06/01 PST