Large diffs are not rendered by default.

@@ -64,13 +64,11 @@
"type" : "overmap_terrain",
"id" : "s_restaurant_deserted_test",
"name" : "abandoned drive-through",
"rotate" : true,
"sym" : 94,
"color" : "dkgray_magenta",
"see_cost" : 5,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true,
"mapgen": [
{ "weight": 1000,
"method": "json", "object": {
@@ -148,7 +146,8 @@
]
}
}
]
],
"flags" : [ "SIDEWALK" ]
},
{
"type" : "terrain",
@@ -171,13 +171,11 @@
"type": "overmap_terrain",
"id" : "bankruptpizzeria",
"name" : "Bankrupt Pizzeria",
"rotate" : true,
"sym" : 94,
"color" : "dark_gray",
"see_cost" : 5,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true,
"mapgen": [
{
"method": "json",
@@ -328,7 +326,8 @@
{ "monster": "GROUP_PIZZAPARLOR_ROBOT", "chance": 1, "x": 1, "y": 13, "density": 0.10 } ],
"comment": "end of mapgen json definition ---v"
},
"comment": "end of mapgen entry ---v"
"comment": "end of mapgen entry ---v",
"flags" : [ "SIDEWALK" ]
}
]
}
@@ -90,38 +90,21 @@
"type" : "overmap_terrain",
"id" : "impact_roof_left",
"name" : "open air",
"rotate" : false,
"line_drawing" : false,
"sym" : 46,
"color" : "blue",
"known_down" : false,
"known_up" : false,
"sidewalk" : false,
"allow_road" : false
"color" : "blue"
},{
"type" : "overmap_terrain",
"id" : "impact_roof_center",
"name" : "open air",
"rotate" : false,
"line_drawing" : false,
"sym" : 46,
"color" : "blue",
"known_down" : false,
"known_up" : false,
"sidewalk" : false,
"allow_road" : false
"flags" : [ "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "impact_roof_right",
"name" : "open air",
"rotate" : false,
"line_drawing" : false,
"sym" : 46,
"color" : "blue",
"known_down" : false,
"known_up" : false,
"sidewalk" : false,
"allow_road" : false
"color" : "blue"
},{
"type" : "overmap_terrain",
"id" : "island_temple_1",
@@ -94,13 +94,11 @@
"type": "overmap_terrain",
"id" : "fieldoffice",
"name" : "wildlife field office",
"rotate" : true,
"sym" : 94,
"color" : "brown",
"see_cost" : 5,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true,
"mapgen": [
{
"method": "json",
@@ -195,7 +193,8 @@
],
"comment": "end of mapgen json definition ---v"
},
"comment": "end of mapgen entry ---v"
"comment": "end of mapgen entry ---v",
"flags" : [ "SIDEWALK" ]
}
]
}
@@ -6,7 +6,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -16,7 +15,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -26,7 +24,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -36,7 +33,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -46,7 +42,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -56,7 +51,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -66,7 +60,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -76,7 +69,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -86,7 +78,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -96,7 +87,6 @@
"sym" : 70,
"color" : "i_white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
}
@@ -6,7 +6,6 @@
"sym" : 46,
"color" : "red",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -16,7 +15,6 @@
"sym" : 46,
"color" : "red",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -26,7 +24,6 @@
"sym" : 46,
"color" : "red",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -36,7 +33,6 @@
"sym" : 46,
"color" : "red",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -46,7 +42,6 @@
"sym" : 46,
"color" : "red",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -56,7 +51,6 @@
"sym" : 46,
"color" : "red",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -66,7 +60,6 @@
"sym" : 46,
"color" : "red",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -76,7 +69,6 @@
"sym" : 46,
"color" : "white",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -86,7 +78,6 @@
"sym" : 46,
"color" : "red",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -96,7 +87,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -106,7 +96,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -116,7 +105,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -126,7 +114,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -136,7 +123,6 @@
"sym" : 46,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -146,7 +132,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -156,7 +141,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -166,7 +150,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -176,7 +159,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -186,7 +168,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -196,7 +177,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -206,7 +186,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -216,7 +195,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -226,7 +204,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -236,7 +213,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -246,7 +222,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -256,7 +231,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -266,7 +240,6 @@
"sym" : 77,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 5,
"mondensity" : 1
},{
@@ -276,7 +249,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -286,7 +258,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -296,7 +267,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -306,7 +276,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -316,7 +285,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -326,7 +294,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -336,7 +303,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -346,7 +312,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -356,7 +321,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
},{
@@ -366,7 +330,6 @@
"sym" : 79,
"color" : "light_gray",
"extras" : "build",
"rotate" : true,
"see_cost" : 99,
"mondensity" : 1
}

Large diffs are not rendered by default.

@@ -459,13 +459,11 @@
"type" : "overmap_terrain",
"id" : "museum",
"name" : "museum",
"rotate" : true,
"sym" : 77,
"color" : "white",
"see_cost" : 5,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true,
"mapgen": [ {
"method": "json",
"comment": "stone wall varient",
@@ -558,7 +556,8 @@
]
}
}
]
],
"flags" : [ "SIDEWALK" ]
},
{
"type" : "mapgen",
@@ -753,13 +752,11 @@
"type" : "overmap_terrain",
"id" : "bowling_alley",
"name" : "bowling alley",
"rotate" : true,
"sym" : 66,
"color" : "red",
"see_cost" : 5,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true,
"mapgen":
[
{
@@ -861,6 +858,7 @@
}
}
}
]
],
"flags" : [ "SIDEWALK" ]
}
]
@@ -6,14 +6,16 @@
"sym" : 70,
"color" : "green",
"see_cost" : 5,
"extras" : "field"
"extras" : "field",
"flags" : [ "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "bandit_garage_2",
"name" : "forest",
"sym" : 70,
"color" : "green",
"see_cost" : 5,
"extras" : "field"
"extras" : "field",
"flags" : [ "NO_ROTATE" ]
}
]
@@ -6,120 +6,109 @@
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_1",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_2",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_3",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_entrance_f2",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_1_f2",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_2_f2",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_3_f2",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_1_r",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_2_r",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "2fmotel_3_r",
"name" : "2-story motel",
"sym" : 104,
"color" : "light_blue",
"see_cost" : 5,
"rotate" : true,
"extras" : "build",
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_1",
@@ -128,7 +117,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_2",
@@ -137,7 +126,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_3",
@@ -146,7 +135,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_4",
@@ -155,7 +144,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_5",
@@ -164,7 +153,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_6",
@@ -173,7 +162,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_7",
@@ -182,7 +171,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_8",
@@ -191,7 +180,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_9",
@@ -200,7 +189,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_10",
@@ -209,7 +198,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_11",
@@ -218,7 +207,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_12",
@@ -227,7 +216,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_13",
@@ -236,7 +225,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_14",
@@ -245,7 +234,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_15",
@@ -254,7 +243,7 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
},{
"type" : "overmap_terrain",
"id" : "loffice_tower_16",
@@ -263,6 +252,6 @@
"color" : "white",
"see_cost" : 5,
"mondensity" : 2,
"sidewalk" : true
"flags" : [ "SIDEWALK", "NO_ROTATE" ]
}
]
@@ -1062,6 +1062,18 @@ Those flags are added by the game code to specific items (that specific welder,
- ```SUR_START``` ... surrounded start, zombies outside the starting shelter.
- ```WIN_START``` ... start in winter.

## Overmap terrains

### Flags

- ```ALLOW_OVERRIDE``` The terrain can be overriden during mapgen (e.g. with a road tile).
- ```KNOWN_DOWN``` There's a known way down.
- ```KNOWN_UP``` There's a known way up.
- ```LINEAR``` For roads etc, which use ID_straight, ID_curved, ID_tee, ID_four_way.
- ```NO_ROTATE``` The terrain can't be rotated (ID_north, ID_east, ID_south, and ID_west instances will NOT be generated, just ID).
- ```RIVER``` It's a river tile.
- ```SIDEWALK``` Has sidewalks on the sides adjacent to roads.

## TODO

- Descriptions for `Special attacks` under `Monsters` could stand to be more descriptive of exactly what the attack does.
@@ -205,9 +205,6 @@ Default: 1000
## 1.3 How "overmap_terrain" variables affect mapgen
"id" is used to determine the required "om_terrain" id for standalone, -except- when the following variables are set in "overmap_terrain":
* "line_drawing": true - For roads etc, which use ID_straight, ID_curved, ID_tee, ID_four_way
The following variables also come into play
* "rotates": true - The terrain will be rotated after generation (to face roads etc). For format mapping, north is always up unless rotated east, etc.
* "extras" - applies rare, random scenes after mapgen; helicoptor crashes, etc
* "mondensity" - determines the default 'density' value for *"place_groups": [ { "monster": ...* (json) or *map:place_monster(..)* (lua)
@@ -582,11 +582,11 @@ struct handler<std::bitset<N>> {
}
template<typename T>
void insert( std::bitset<N> &container, const T &data ) const {
container.insert( data );
container.set( data );
}
template<typename T>
void erase( std::bitset<N> &container, const T &data ) const {
container.erase( data );
container.reset( data );
}
static constexpr bool is_container = true;
};
@@ -1738,7 +1738,7 @@ void mapgen_function_json::generate( map *m, const oter_id &terrain_type, const

m->rotate( rotation.get() );

if( terrain_type->has_flag(rotates) ) {
if( terrain_type->is_rotatable() ) {
mapgen_rotate(m, terrain_type, false );
}
}
@@ -107,12 +107,12 @@ struct overmap_static_spawns : public overmap_spawns {

//terrain flags enum! this is for tracking the indices of each flag.
enum oter_flags {
known_down = 0,
allow_override = 0,
known_down,
known_up,
no_rotate, // this tile doesn't have four rotated versions (north, east, south, west)
river_tile,
has_sidewalk,
allow_road,
rotates, // does this tile have four versions, one for each direction?
line_drawing, // does this tile have 8 versions, including straights, bends, tees, and a fourway?
num_oter_flags
};
@@ -154,6 +154,10 @@ struct oter_type_t {
void check() const;
void finalize();

bool is_rotatable() const {
return !has_flag( no_rotate ) && !has_flag( line_drawing );
}

private:
std::bitset<num_oter_flags> flags;
std::vector<oter_id> directional_peers;
@@ -226,6 +230,12 @@ struct oter_t {
return type->has_flag( flag );
}

bool is_hardcoded() const;

bool is_rotatable() const {
return type->is_rotatable();
}

private:
om_direction::type dir = om_direction::type::none;
long sym = '\0'; // This is a long, so we can support curses linedrawing.
@@ -190,6 +190,16 @@ generic_factory<overmap_special> specials( "overmap special" );

}

static const std::map<std::string, oter_flags> oter_flags_map = {
{ "KNOWN_DOWN", known_down },
{ "KNOWN_UP", known_up },
{ "RIVER", river_tile },
{ "SIDEWALK", has_sidewalk },
{ "ALLOW_OVERRIDE", allow_override },
{ "NO_ROTATE", no_rotate },
{ "LINEAR", line_drawing }
};

/*
* Temporary container id_or_id. Stores str for delayed lookup and conversion.
*/
@@ -368,7 +378,7 @@ bool is_ot_type(const std::string &otype, const oter_id &oter)

bool road_allowed(const oter_id &ter)
{
return ter->has_flag( allow_road );
return ter->has_flag( allow_override );
}

oter_id overmap::random_shop() const
@@ -436,20 +446,14 @@ void oter_type_t::load( JsonObject &jo, const std::string &src )

optional( jo, was_loaded, "color", color, color_reader{} );

set_flag( rotates, jo.get_bool( "rotate", false ) );
set_flag( line_drawing, jo.get_bool( "line_drawing", false ) );
set_flag( known_down, jo.get_bool( "known_down", false ) );
set_flag( known_up, jo.get_bool( "known_up", false ) );
set_flag( has_sidewalk, jo.get_bool( "sidewalk", false ) );
set_flag( allow_road, jo.get_bool( "allow_road", false ) );
set_flag( river_tile, id.str().compare( 0, 5, "river", 5 ) == 0 ||
id.str().compare( 0, 6, "bridge", 6 ) == 0 );

if( has_flag( rotates ) && has_flag( line_drawing ) ) {
jo.throw_error( "Can't have \"rotate\" and \"line_drawing\" at the same time." );
}
const typed_flag_reader<decltype( oter_flags_map )> flag_reader{ oter_flags_map, "invalid overmap terrain flag" };
optional( jo, was_loaded, "flags", flags, flag_reader );

if( has_flag( line_drawing ) ) {
if( has_flag( no_rotate ) ) {
jo.throw_error( "Mutually exclusive flags: \"NO_ROTATE\" and \"LINEAR\"." );
}

for( const auto &elem : om_lines::mapgen_suffixes ) {
load_overmap_terrain_mapgens( jo, id.str(), elem );
}
@@ -462,7 +466,7 @@ void oter_type_t::finalize()
{
directional_peers.clear(); // In case of a second finalization.

if( has_flag( rotates ) ) {
if( is_rotatable() ) {
for( auto dir : om_direction::all ) {
register_terrain( oter_t( *this, dir ), static_cast<size_t>( dir ), om_direction::size );
}
@@ -501,7 +505,7 @@ oter_id oter_type_t::get_rotated( om_direction::type dir ) const
if( dir == om_direction::type::invalid ) {
debugmsg( "Invalid rotation was asked from overmap terrain \"%s\".", id.c_str() );
return ot_null;
} else if( dir == om_direction::type::none || !has_flag( rotates ) ) {
} else if( dir == om_direction::type::none || !is_rotatable() ) {
return directional_peers.front();
}
assert( directional_peers.size() == om_direction::size );
@@ -587,12 +591,7 @@ bool oter_t::has_connection( om_direction::type dir ) const
return om_lines::has_segment( line, dir );
}

void overmap_terrains::load( JsonObject &jo, const std::string &src )
{
terrain_types.load( jo, src );
}

void overmap_terrains::check_consistency()
bool oter_t::is_hardcoded() const
{
// @todo This set only exists because so does the monstrous 'if-else' statement in @ref map::draw_map(). Get rid of both.
static const std::set<std::string> hardcoded_mapgen = {
@@ -659,6 +658,16 @@ void overmap_terrains::check_consistency()
"triffid_roots",
};

return hardcoded_mapgen.find( get_mapgen_id() ) != hardcoded_mapgen.end();
}

void overmap_terrains::load( JsonObject &jo, const std::string &src )
{
terrain_types.load( jo, src );
}

void overmap_terrains::check_consistency()
{
for( const auto &elem : terrain_types.get_all() ) {
if( elem.static_spawns.group && !elem.static_spawns.group.is_valid() ) {
debugmsg( "Invalid monster group \"%s\" in spawns of \"%s\".", elem.static_spawns.group.c_str(), elem.id.c_str() );
@@ -672,7 +681,7 @@ void overmap_terrains::check_consistency()
continue;
}

const bool exists_hardcoded = hardcoded_mapgen.find( mid ) != hardcoded_mapgen.end();
const bool exists_hardcoded = elem.is_hardcoded();
const bool exists_loaded = oter_mapgen.find( mid ) != oter_mapgen.end();

if( exists_loaded ) {
@@ -1153,21 +1162,39 @@ void overmap_special::finalize()

void overmap_special::check() const
{
// Update and check terrains and connections.
std::set<int> invalid_terrains;
std::set<int> fixed_terrains;
std::set<tripoint> points;

for( const auto &elem : terrains ) {
if( !elem.terrain.is_valid() ) {
debugmsg( "Invalid terrain \"%s\" in overmap special \"%s\".",
elem.terrain.c_str(), id.c_str() );
continue;
const auto &oter = elem.terrain;

if( oter.is_valid() ) {
if( rotatable ) {
// We assume that the hardcoded mapgen takes care of rotation (in most cases it really does).
const bool loose_terrain = oter->is_rotatable() || oter->has_flag( line_drawing ) || oter->is_hardcoded();

if( !loose_terrain && fixed_terrains.count( oter.id() ) == 0 ) {
fixed_terrains.insert( oter.id() );
debugmsg( "In overmap special \"%s\" (which is rotatable), terrain \"%s\" can't be rotated.",
id.c_str(), oter.c_str() );
}
}
} else {
if( invalid_terrains.count( oter.id() ) == 0 ) {
invalid_terrains.insert( oter.id() );
debugmsg( "In overmap special \"%s\", terrain \"%s\" is invalid.",
id.c_str(), oter.c_str() );
}
}

if( points.count( elem.p ) > 0 ) {
const auto &pos = elem.p;

if( points.count( pos ) > 0 ) {
debugmsg( "In overmap special \"%s\", point [%d,%d,%d] is duplicated.",
id.c_str(), elem.p.x, elem.p.y, elem.p.z );
id.c_str(), pos.x, pos.y, pos.z );
} else {
points.insert( elem.p );
points.insert( pos );
}
}

@@ -2714,7 +2741,7 @@ tripoint overmap::draw_overmap(const tripoint &orig, const draw_data_t &data)
uistate.place_special = oslist[pmenu.ret];
}
// @todo Unify these things.
const bool can_rotate = terrain ? uistate.place_terrain->has_flag( rotates ) : uistate.place_special->rotatable;
const bool can_rotate = terrain ? uistate.place_terrain->is_rotatable() : uistate.place_special->rotatable;

uistate.omedit_rotation = om_direction::type::none;
// If user chose an already rotated submap, figure out its direction
@@ -2751,7 +2778,7 @@ tripoint overmap::draw_overmap(const tripoint &orig, const draw_data_t &data)
mvwprintz( w_editor, 7, 1, c_red, _("generated. Their overmap") );
mvwprintz( w_editor, 8, 1, c_red, _("id will change, but not") );
mvwprintz( w_editor, 9, 1, c_red, _("their contents.") );
if( ( terrain && uistate.place_terrain->has_flag( rotates ) ) ||
if( ( terrain && uistate.place_terrain->is_rotatable() ) ||
( !terrain && uistate.place_special->rotatable ) ) {
mvwprintz( w_editor, 11, 1, c_white, _("[%s] Rotate"),
ctxt.get_desc( "ROTATE" ).c_str() );
@@ -3326,7 +3353,7 @@ void overmap::build_city_street( int x, int y, int cs, om_direction::type dir, c

// Grow in the stated direction, sprouting off sub-roads and placing buildings as we go.
while( c > 0 && inbounds( x, y, 0, 1 ) &&
(ter(x + bias.x, y + bias.y, 0)->has_flag( allow_road ) || c == cs) ) {
(ter(x + bias.x, y + bias.y, 0)->has_flag( allow_override ) || c == cs) ) {
x += bias.x;
y += bias.y;
c--;
@@ -3348,15 +3375,15 @@ void overmap::build_city_street( int x, int y, int cs, om_direction::type dir, c
}

// Look to each side, and branch if the way is clear.
if (c < croad - 1 && c >= 2 && ( ter(x + bias.y, y + bias.x, 0)->has_flag( allow_road ) &&
ter(x - bias.y, y - bias.x, 0)->has_flag( allow_road ) ) ) {
if (c < croad - 1 && c >= 2 && ( ter(x + bias.y, y + bias.x, 0)->has_flag( allow_override ) &&
ter(x - bias.y, y - bias.x, 0)->has_flag( allow_override ) ) ) {
croad = c;
build_city_street( x, y, cs - rng( 1, 3 ), om_direction::turn_left( dir ), town );
build_city_street( x, y, cs - rng( 1, 3 ), om_direction::turn_right( dir ), town );
}
}
// Now we're done growing, if there's a road ahead, add one more road segment to meet it.
if( get_ter( x + bias.x, y + bias.y, 0 )->has_flag( allow_road ) &&
if( get_ter( x + bias.x, y + bias.y, 0 )->has_flag( allow_override ) &&
get_ter( x + 2 * bias.x, y + 2 * bias.y, 0 )->can_connect_to( road->get_first() ) ) {

ter( x + bias.x, y + bias.y, 0 ) = road->get_first();