Remove the message about dmd not being performant, improve chances() and make it...
[SmugglerRL.git] / src / mapgen.d
blob15ba4aa5321d707139843639290edd539ecc7954
1 import constants;
2 import game;
3 import std.random: uniform;
4 import util;
6 // 1/a chance of any tile being walkable
7 private void map_random(Game g, int[] flags) {
8 int a, b;
9 a = 1;
10 b = 2;
11 if (flags.length == 1) {
12 b = flags[0];
13 if (flags[0] < 0) {
14 b = -b;
15 a = b-1;
18 if (flags.length == 2) {
19 a = flags[0];
20 b = flags[1];
23 foreach (int tmpy; 0..map_y+1) {
24 foreach (int tmpx; 0..map_x+1) {
25 g.map[tmpy][tmpx].walkable = chances(a, b);
26 g.map[tmpy][tmpx].blocks_light = !g.map[tmpy][tmpx].walkable;
31 private void mapcaves_postprocess(Game g) {
32 foreach (int y; 1..map_y+1) {
33 foreach (int x; 1..map_x+1) {
34 if ((g.map[y+1][x].walkable && g.map[y-1][x].walkable) || (g.map[y][x+1].walkable && g.map[y][x-1].walkable)) {
35 g.map[y][x].walkable = true;
36 g.map[y][x].blocks_light = false;
42 @safe private void map_caves(Game g, int[] flags, int iters = 1000) {
43 import std.stdio;
44 enum Direction: bool {y = true, x = false}
45 enum Sign: bool {plus = true, minus = false}
46 bool d = Direction.x;
47 bool s = Sign.plus;
48 foreach (tmpy; 0..map_y+1) {
49 foreach (tmpx; 0..map_x+1) {
50 g.map[tmpy][tmpx].walkable = false;
51 g.map[tmpy][tmpx].blocks_light = true;
55 int tmpx, tmpy;
56 // "burrow" through the cave
58 tmpy = uniform(0, map_y);
59 tmpx = uniform(0, map_x);
60 foreach (_; 0..uniform(8000, 9000)) {
61 foreach (__; 0..uniform(3, 20)) {
63 // we hit an edge, reverse direction
64 if ((tmpx >= map_x) || (tmpy >= map_y)) {
65 s = Sign.minus;
66 continue;
67 } else if ((tmpx <= 2) || (tmpy <= 2)) {
68 s = Sign.plus;
69 continue;
72 foreach (i; tmpx-uniform(-1, 3)..tmpx+uniform(-1, 3)) {
73 // we hit an edge, try again
74 if ((i > map_x) || (i < 2)) {
75 map_caves(g, []);
76 return;
78 g.map[tmpy][i].walkable = true;
79 g.map[tmpy][i].blocks_light = false;
81 foreach (i; tmpy-uniform(-1, 3)..tmpy+uniform(-1, 3)) {
82 // ditto
83 if ((i > map_y) || (i < 2)) {
84 map_caves(g, []);
85 return;
87 g.map[i][tmpx].walkable = true;
88 g.map[i][tmpx].blocks_light = false;
93 if (d/* == Direction.x*/) {
94 if (s == Sign.plus)
95 tmpx++;
96 else
97 tmpx--;
98 } else /*if (d == Direction.y)*/ {
99 if (s == Sign.plus)
100 tmpy++;
101 else
102 tmpy--;
105 if (uniform(0, 3)) {
106 d = !d;
108 if (uniform(0, 3)) {
109 s = !s;
113 /+ if (chances(iters, 1001)) {
114 map_caves(g, [], iters-1);
120 /* Prototypes for different types of dungeons */
121 enum MapType {
122 random,
123 caves
126 private enum int[][MapType] argnums = [MapType.random: [0, 1, 2], MapType.caves: [0]];
128 /* Map from a maptype to an array of ints. Those are all the different numbers
129 * of args it can take. So, for example, it might have an option of taking 4
130 * OR 5 args
133 private void veriflags(MapType type, ulong flags) {
134 bool[ulong] tmp;
135 foreach (i; argnums[type]) {
136 tmp[i] = false;
138 assert (flags in tmp);
141 void genmap(Game g, MapType type, int[] flags = []) {
142 veriflags(type, flags.length);
143 switch(type) {
144 case MapType.random:
145 map_random(g, flags);
146 return;
147 case MapType.caves:
148 map_caves(g, flags);
149 map_caves(g, flags);
150 map_caves(g, flags);
151 mapcaves_postprocess(g);
152 mapcaves_postprocess(g);
153 mapcaves_postprocess(g);
154 return;
155 default: break;
157 assert(0);