forked from amitp/mapgen2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Roads.as
84 lines (73 loc) · 3.05 KB
/
Roads.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Place roads on the polygonal island map roughly following contour lines.
// Author: [email protected]
// License: MIT
package {
import graph.*;
public class Roads {
// The road array marks the edges that are roads. The mark is 1,
// 2, or 3, corresponding to the three contour levels. Note that
// these are sparse arrays, only filled in where there are roads.
public var road:Array; // edge index -> int contour level
public var roadConnections:Array; // center index -> array of Edges with roads
public function Roads() {
road = [];
roadConnections = [];
}
// We want to mark different elevation zones so that we can draw
// island-circling roads that divide the areas.
public function createRoads(map:Map):void {
// Oceans and coastal polygons are the lowest contour zone
// (1). Anything connected to contour level K, if it's below
// elevation threshold K, or if it's water, gets contour level
// K. (2) Anything not assigned a contour level, and connected
// to contour level K, gets contour level K+1.
var queue:Array = [];
var p:Center, q:Corner, r:Center, edge:Edge, newLevel:int;
var elevationThresholds:Array = [0, 0.05, 0.37, 0.64];
var cornerContour:Array = []; // corner index -> int contour level
var centerContour:Array = []; // center index -> int contour level
for each (p in map.centers) {
if (p.coast || p.ocean) {
centerContour[p.index] = 1;
queue.push(p);
}
}
while (queue.length > 0) {
p = queue.shift();
for each (r in p.neighbors) {
newLevel = centerContour[p.index] || 0;
while (r.elevation > elevationThresholds[newLevel] && !r.water) {
// NOTE: extend the contour line past bodies of
// water so that roads don't terminate inside lakes.
newLevel += 1;
}
if (newLevel < (centerContour[r.index] || 999)) {
centerContour[r.index] = newLevel;
queue.push(r);
}
}
}
// A corner's contour level is the MIN of its polygons
for each (p in map.centers) {
for each (q in p.corners) {
cornerContour[q.index] = Math.min(cornerContour[q.index] || 999,
centerContour[p.index] || 999);
}
}
// Roads go between polygons that have different contour levels
for each (p in map.centers) {
for each (edge in p.borders) {
if (edge.v0 && edge.v1
&& cornerContour[edge.v0.index] != cornerContour[edge.v1.index]) {
road[edge.index] = Math.min(cornerContour[edge.v0.index],
cornerContour[edge.v1.index]);
if (!roadConnections[p.index]) {
roadConnections[p.index] = [];
}
roadConnections[p.index].push(edge);
}
}
}
}
}
}