Skip to content

Commit

Permalink
Merge pull request #24431 from BrianLefler/nested_neighbors_improvements
Browse files Browse the repository at this point in the history
Improve place_nested: Fuzzy neighbor matching and an else option
  • Loading branch information
ZhilkinSerg committed Jul 23, 2018
2 parents d659bd4 + d59ed4e commit 56a2166
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 88 deletions.
12 changes: 6 additions & 6 deletions data/json/mapgen/lab/lab_common.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@
"object": {
"mapgensize": [ 24, 24 ],
"place_nested": [
{ "chunks": [ "sub_t_concrete_wall" ], "x": 11, "y": 23, "neighbors": { "south": ["empty_rock"] } },
{ "chunks": [ "sub_t_concrete_wall" ], "x": 12, "y": 23, "neighbors": { "south": ["empty_rock"] } },
{ "chunks": [ "sub_t_concrete_wall" ], "x": 23, "y": 11, "neighbors": { "east": ["empty_rock"] } },
{ "chunks": [ "sub_t_concrete_wall" ], "x": 23, "y": 12, "neighbors": { "east": ["empty_rock"] } },
{ "chunks": [ "lab_north_wall" ], "x": 0, "y": 0, "neighbors": { "north": ["empty_rock"] } },
{ "chunks": [ "lab_west_wall" ], "x": 0, "y": 0, "neighbors": { "west": ["empty_rock"] } }
{ "else_chunks": [ "sub_t_concrete_wall" ], "x": 11, "y": 23, "neighbors": { "south": ["lab"] } },
{ "else_chunks": [ "sub_t_concrete_wall" ], "x": 12, "y": 23, "neighbors": { "south": ["lab"] } },
{ "else_chunks": [ "sub_t_concrete_wall" ], "x": 23, "y": 11, "neighbors": { "east": ["lab"] } },
{ "else_chunks": [ "sub_t_concrete_wall" ], "x": 23, "y": 12, "neighbors": { "east": ["lab"] } },
{ "else_chunks": [ "lab_north_wall" ], "x": 0, "y": 0, "neighbors": { "north": ["lab"] } },
{ "else_chunks": [ "lab_west_wall" ], "x": 0, "y": 0, "neighbors": { "west": ["lab"] } }
]
}
},
Expand Down
24 changes: 12 additions & 12 deletions data/json/mapgen/lab/lab_floorplan_cross.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,18 +174,18 @@
"object": {
"mapgensize": [ 24, 24 ],
"place_nested": [
{ "chunks": [ "lab_nw_rock" ], "x": 0, "y": 0, "neighbors": { "north": "empty_rock" } },
{ "chunks": [ "lab_nw_rock" ], "x": 0, "y": 0, "neighbors": { "west": "empty_rock" } },
{ "chunks": [ "lab_ne_rock" ], "x": 13, "y": 0, "neighbors": { "north": "empty_rock" } },
{ "chunks": [ "lab_ne_rock" ], "x": 13, "y": 0, "neighbors": { "east": "empty_rock" } },
{ "chunks": [ "lab_sw_rock" ], "x": 0, "y": 13, "neighbors": { "south": "empty_rock" } },
{ "chunks": [ "lab_sw_rock" ], "x": 0, "y": 13, "neighbors": { "west": "empty_rock" } },
{ "chunks": [ "lab_se_rock" ], "x": 13, "y": 13, "neighbors": { "south": "empty_rock" } },
{ "chunks": [ "lab_se_rock" ], "x": 13, "y": 13, "neighbors": { "east": "empty_rock" } },
{ "chunks": [ [ "lab_n_rock", 100 ], [ "lab_n_vault", 30 ] ], "x": 0, "y": 0, "neighbors": { "north": "empty_rock" } },
{ "chunks": [ [ "lab_w_rock", 100 ], [ "lab_w_vault", 30 ] ], "x": 0, "y": 0, "neighbors": { "west": "empty_rock" } },
{ "chunks": [ [ "lab_s_rock", 100 ], [ "lab_s_vault", 30 ] ], "x": 0, "y": 0, "neighbors": { "south": "empty_rock" } },
{ "chunks": [ [ "lab_e_rock", 100 ], [ "lab_e_vault", 30 ] ], "x": 0, "y": 0, "neighbors": { "east": "empty_rock" } }
{ "else_chunks": [ "lab_nw_rock" ], "x": 0, "y": 0, "neighbors": { "north": "lab" } },
{ "else_chunks": [ "lab_nw_rock" ], "x": 0, "y": 0, "neighbors": { "west": "lab" } },
{ "else_chunks": [ "lab_ne_rock" ], "x": 13, "y": 0, "neighbors": { "north": "lab" } },
{ "else_chunks": [ "lab_ne_rock" ], "x": 13, "y": 0, "neighbors": { "east": "lab" } },
{ "else_chunks": [ "lab_sw_rock" ], "x": 0, "y": 13, "neighbors": { "south": "lab" } },
{ "else_chunks": [ "lab_sw_rock" ], "x": 0, "y": 13, "neighbors": { "west": "lab" } },
{ "else_chunks": [ "lab_se_rock" ], "x": 13, "y": 13, "neighbors": { "south": "lab" } },
{ "else_chunks": [ "lab_se_rock" ], "x": 13, "y": 13, "neighbors": { "east": "lab" } },
{ "else_chunks": [ [ "lab_n_rock", 100 ], [ "lab_n_vault", 30 ] ], "x": 0, "y": 0, "neighbors": { "north": "lab" } },
{ "else_chunks": [ [ "lab_w_rock", 100 ], [ "lab_w_vault", 30 ] ], "x": 0, "y": 0, "neighbors": { "west": "lab" } },
{ "else_chunks": [ [ "lab_s_rock", 100 ], [ "lab_s_vault", 30 ] ], "x": 0, "y": 0, "neighbors": { "south": "lab" } },
{ "else_chunks": [ [ "lab_e_rock", 100 ], [ "lab_e_vault", 30 ] ], "x": 0, "y": 0, "neighbors": { "east": "lab" } }
]
}
},
Expand Down
12 changes: 6 additions & 6 deletions data/json/mapgen/lab/lab_floorplans.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
"place_nested": [
{ "chunks": [ "lab_spawn_9x9_crossdoors" ], "x": 1, "y": 1 },
{ "chunks": [ "lab_spawn_9x9_crossdoors" ], "x": 14, "y": 1 },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "east": ["lab", "lab_stairs", "ice_lab", "ice_lab_stairs"] } },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "south": ["lab", "lab_stairs", "ice_lab", "ice_lab_stairs"] } }
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "east": ["lab"] } },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "south": ["lab"] } }
]
}
},
Expand Down Expand Up @@ -133,8 +133,8 @@
},
"place_nested": [
{ "chunks": [ [ "null", 90 ], [ "lab_hulk_smash", 10 ] ], "x": 0, "y": 0 },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "east": ["lab", "lab_stairs", "ice_lab", "ice_lab_stairs"] } },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "south": ["lab", "lab_stairs", "ice_lab", "ice_lab_stairs"] } }
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "east": ["lab"] } },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "south": ["lab"] } }
]
}
},
Expand Down Expand Up @@ -232,8 +232,8 @@
},
"place_nested": [
{ "chunks": [ [ "null", 90 ], [ "lab_hulk_smash", 10 ] ], "x": 0, "y": 0 },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "east": ["lab", "lab_stairs", "ice_lab", "ice_lab_stairs"] } },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "south": ["lab", "lab_stairs", "ice_lab", "ice_lab_stairs"] } }
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "east": ["lab"] } },
{ "chunks": [ "lab_north_doors" ], "x": 11, "y": 0, "neighbors": { "south": ["lab"] } }
]
}
},
Expand Down
117 changes: 53 additions & 64 deletions src/mapgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,18 @@ class jmapgen_computer : public jmapgen_piece {
}
};

static void load_weighted_entries(JsonObject &jsi, std::string json_key, weighted_int_list<std::string>& list) {
JsonArray jarr = jsi.get_array( json_key );
while( jarr.has_more() ) {
if( jarr.test_array() ) {
JsonArray inner = jarr.next_array();
list.add( inner.get_string( 0 ), inner.get_int( 1 ) );
} else {
list.add( jarr.next_string(), 100 );
}
}
}

/**
* Calls another mapgen call inside the current one.
* Note: can't use regular overmap ids.
Expand All @@ -1239,40 +1251,39 @@ class jmapgen_nested : public jmapgen_piece {
return true;
}

bool all_directions_match = true;
for( om_direction::type dir : om_direction::all ) {
int index = static_cast<int>( dir );
const std::set<oter_str_id> &allowed_neighbors = neighbors[index];
if( !allowed_neighbors.empty() && allowed_neighbors.count( dat.neighbor_at( dir ).id() ) == 0 ) {
return false;

if (allowed_neighbors.empty()) {
continue; // no constraints on this direction, skip.
}
}

return true;
bool this_direction_matches = false;
for( oter_str_id allowed_neighbor : allowed_neighbors ) {
this_direction_matches |= is_ot_subtype(allowed_neighbor.c_str(), dat.neighbor_at( dir ).id() );
}
all_directions_match &= this_direction_matches;
}
return all_directions_match;
}
};

public:
weighted_int_list<std::string> entries;
weighted_int_list<std::string> else_entries;
neighborhood_check neighbors;
jmapgen_nested( JsonObject &jsi ) : jmapgen_piece(), neighbors( jsi.get_object( "neighbors" ) )
{
JsonArray jarr = jsi.get_array( "chunks" );
while( jarr.has_more() ) {
if( jarr.test_array() ) {
JsonArray inner = jarr.next_array();
entries.add( inner.get_string( 0 ), inner.get_int( 1 ) );
} else {
entries.add( jarr.next_string(), 100 );
}
}
load_weighted_entries(jsi, "chunks", entries);
load_weighted_entries(jsi, "else_chunks", else_entries);
}
void apply( const mapgendata &dat, const jmapgen_int &x, const jmapgen_int &y, const float d ) const override
{
const std::string *res = entries.pick();
const std::string *res = neighbors.test( dat ) ? entries.pick() : else_entries.pick();
if( res == nullptr || res->empty() || *res == "null" ) {
return;
}

if( !neighbors.test( dat ) ) {
// This will be common when neighbors.test(...) is false, since else_entires is often empty.
return;
}

Expand Down Expand Up @@ -2837,32 +2848,22 @@ ___DEEE|.R.|...,,...|sss\n",
rotate(3);
}
} else if (tw != 0 || rw != 0 || lw != 0 || bw != 0) { // Sewers!
// @todo: This checks if id is a laboratory the hard-coded way. Get rid of the hardcode.
const auto is_lab = []( const oter_id &id ) {
return is_ot_type( "lab", id ) ||
is_ot_type( "lab_stairs", id ) ||
is_ot_type( "lab_core", id ) ||
is_ot_type( "ice_lab", id ) ||
is_ot_type( "ice_lab_stairs", id ) ||
is_ot_type( "ice_lab_core", id );
};

for (int i = 0; i < SEEX * 2; i++) {
for (int j = 0; j < SEEY * 2; j++) {
ter_set(i, j, t_rock_floor);
if (((i < lw || i > SEEX * 2 - 1 - rw) && j > SEEY - 3 && j < SEEY + 2) ||
((j < tw || j > SEEY * 2 - 1 - bw) && i > SEEX - 3 && i < SEEX + 2)) {
ter_set(i, j, t_sewage);
}
if( ( i == 0 && is_lab( t_east ) ) || i == SEEX * 2 - 1 ) {
if( ( i == 0 && is_ot_subtype( "lab", t_east ) ) || i == SEEX * 2 - 1 ) {
if (ter(i, j) == t_sewage) {
ter_set(i, j, t_bars);
} else if (j == SEEY - 1 || j == SEEY) {
ter_set(i, j, t_door_metal_c);
} else {
ter_set(i, j, t_concrete_wall);
}
} else if( ( j == 0 && is_lab( t_north ) ) || j == SEEY * 2 - 1 ) {
} else if( ( j == 0 && is_ot_subtype( "lab", t_north ) ) || j == SEEY * 2 - 1 ) {
if (ter(i, j) == t_sewage) {
ter_set(i, j, t_bars);
} else if (i == SEEX - 1 || i == SEEX) {
Expand All @@ -2875,18 +2876,11 @@ ___DEEE|.R.|...,,...|sss\n",
}
} else { // We're below ground, and no sewers
// Set up the boundaries of walls (connect to adjacent lab squares)
// Are we in an ice lab?
if ( ice_lab ) {
tw = is_ot_type("ice_lab", t_north) ? 0 : 2;
rw = is_ot_type("ice_lab", t_east) ? 1 : 2;
bw = is_ot_type("ice_lab", t_south) ? 1 : 2;
lw = is_ot_type("ice_lab", t_west) ? 0 : 2;
} else {
tw = is_ot_type("lab", t_north) ? 0 : 2;
rw = is_ot_type("lab", t_east) ? 1 : 2;
bw = is_ot_type("lab", t_south) ? 1 : 2;
lw = is_ot_type("lab", t_west) ? 0 : 2;
}
tw = is_ot_subtype("lab", t_north) ? 0 : 2;
rw = is_ot_subtype("lab", t_east) ? 1 : 2;
bw = is_ot_subtype("lab", t_south) ? 1 : 2;
lw = is_ot_subtype("lab", t_west) ? 0 : 2;

int boarders = 0;
if (tw == 0 ) {
boarders++;
Expand Down Expand Up @@ -2927,14 +2921,14 @@ ___DEEE|.R.|...,,...|sss\n",
}
const auto predicate = [this]( const tripoint &p ) { return ter( p ) == t_rock_floor; };
const auto range = points_in_rectangle( { lw, tw, abs_sub.z }, { SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, abs_sub.z } );
if (t_above == "lab_stairs" || t_above == "ice_lab_stairs") {
if (is_ot_subtype("stairs", t_above)) {
if( const auto p = random_point( range, predicate ) ) {
remove_trap( *p );
ter_set( *p, t_stairs_up );
}
}

if (terrain_type == "lab_stairs" || terrain_type == "ice_lab_stairs") {
if (is_ot_subtype("stairs", terrain_type)) {
if( const auto p = random_point( range, predicate ) ) {
remove_trap( *p );
ter_set( *p, t_stairs_down );
Expand Down Expand Up @@ -2990,12 +2984,12 @@ ___DEEE|.R.|...,,...|sss\n",
}
}

if (t_above == "lab_stairs" || t_above == "ice_lab_stairs") {
if (is_ot_subtype("stairs", t_above)) {
if( const auto p = random_point( points_in_rectangle( { lw, tw, abs_sub.z }, { SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, abs_sub.z } ), [this]( const tripoint &n ) { return ter( n ) == t_rock_floor; } ) ) {
ter_set( *p, t_stairs_up );
}
}
if (terrain_type == "lab_stairs" || terrain_type == "ice_lab_stairs") {
if (is_ot_subtype("stairs", terrain_type)) {
if( const auto p = random_point( points_in_rectangle( { lw, tw, abs_sub.z }, { SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, abs_sub.z } ), [this]( const tripoint &n ) { return ter( n ) == t_rock_floor; } ) ) {
ter_set( *p, t_stairs_down );
}
Expand All @@ -3022,7 +3016,7 @@ ___DEEE|.R.|...,,...|sss\n",
}
}
}
if (t_above == "lab_stairs" || t_above == "ice_lab_stairs") {
if (is_ot_subtype("stairs", t_above)) {
ter_set(rng(SEEX - 1, SEEX), rng(SEEY - 1, SEEY), t_stairs_up);
}
// Top left
Expand Down Expand Up @@ -3067,7 +3061,7 @@ ___DEEE|.R.|...,,...|sss\n",
ter_set(SEEX - 1, SEEY * 2 - 1, t_door_metal_c);
ter_set(SEEX , SEEY * 2 - 1, t_door_metal_c);
}
if (terrain_type == "lab_stairs" || terrain_type == "ice_lab_stairs") { // Stairs going down
if (is_ot_subtype("stairs", terrain_type)) { // Stairs going down
std::vector<point> stair_points;
if (tw != 0) {
stair_points.push_back(point(SEEX - 1, 2));
Expand Down Expand Up @@ -3119,7 +3113,7 @@ ___DEEE|.R.|...,,...|sss\n",
}
}
}
if (t_above == "lab_stairs" || t_above == "ice_lab_stairs") {
if (is_ot_subtype("stairs", t_above)) {
ter_set(SEEX - 1, SEEY - 1, t_stairs_up);
ter_set(SEEX , SEEY - 1, t_stairs_up);
ter_set(SEEX - 1, SEEY , t_stairs_up);
Expand Down Expand Up @@ -3154,7 +3148,7 @@ ___DEEE|.R.|...,,...|sss\n",
ter_set(SEEX - 1, SEEY * 2 - 1, t_door_metal_c);
ter_set(SEEX , SEEY * 2 - 1, t_door_metal_c);
}
if (terrain_type == "lab_stairs" || terrain_type == "ice_lab_stairs") {
if (is_ot_subtype("stairs", terrain_type)) {
ter_set(SEEX - 3 + 5 * rng(0, 1), SEEY - 3 + 5 * rng(0, 1), t_stairs_down);
}
break;
Expand All @@ -3173,7 +3167,7 @@ ___DEEE|.R.|...,,...|sss\n",
}
science_room(this, lw, tw, SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw,
zlevel, rng(0, 3));
if (t_above == "lab_stairs" || t_above == "ice_lab_stairs") {
if (is_ot_subtype("stairs", t_above)) {
if( const auto p = random_point( points_in_rectangle( { lw, tw, abs_sub.z }, { SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, abs_sub.z } ), [this]( const tripoint &n ) { return ter( n ) == t_rock_floor; } ) ) {
ter_set( *p, t_stairs_up );
}
Expand All @@ -3186,7 +3180,7 @@ ___DEEE|.R.|...,,...|sss\n",
ter_set(SEEX - 1, SEEY * 2 - 1, t_door_metal_c);
ter_set(SEEX , SEEY * 2 - 1, t_door_metal_c);
}
if (terrain_type == "lab_stairs" || terrain_type == "ice_lab_stairs") {
if (is_ot_subtype("stairs", terrain_type)) {
if( const auto p = random_point( points_in_rectangle( { lw, tw, abs_sub.z }, { SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, abs_sub.z } ), [this]( const tripoint &n ) { return ter( n ) == t_rock_floor; } ) ) {
ter_set( *p, t_stairs_down );
}
Expand Down Expand Up @@ -3273,18 +3267,13 @@ ___DEEE|.R.|...,,...|sss\n",
if ( ice_lab ) {
int temperature = -20 + 30 * zlevel;
set_temperature(x, y, temperature);

tw = is_ot_type("ice_lab", t_north) ? 0 : 2;
rw = is_ot_type("ice_lab", t_east) ? 1 : 2;
bw = is_ot_type("ice_lab", t_south) ? 1 : 2;
lw = is_ot_type("ice_lab", t_west) ? 0 : 2;
} else {
tw = is_ot_type("lab", t_north) ? 0 : 2;
rw = is_ot_type("lab", t_east) ? 1 : 2;
bw = is_ot_type("lab", t_south) ? 1 : 2;
lw = is_ot_type("lab", t_west) ? 0 : 2;
}

tw = is_ot_subtype("lab", t_north) ? 0 : 2;
rw = is_ot_subtype("lab", t_east) ? 1 : 2;
bw = is_ot_subtype("lab", t_south) ? 1 : 2;
lw = is_ot_subtype("lab", t_west) ? 0 : 2;

const std::string function_key = "lab_finale_1level";
const auto fmapit = oter_mapgen.find( function_key );
const int hardcoded_finale_map_weight = 500; // weight of all hardcoded maps.
Expand Down Expand Up @@ -3531,12 +3520,12 @@ ___DEEE|.R.|...,,...|sss\n",
} // end use_hardcoded_lab_finale

// Handle stairs in the unlikely case they are needed.
if (t_above == "lab_stairs" || t_above == "ice_lab_stairs") {
if (is_ot_subtype("stairs", t_above)) {
if( const auto p = random_point( points_in_rectangle( { lw, tw, abs_sub.z }, { SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, abs_sub.z } ), [this]( const tripoint &n ) { return ter( n ) == t_rock_floor; } ) ) {
ter_set( *p, t_stairs_up );
}
}
if (terrain_type == "lab_stairs" || terrain_type == "ice_lab_stairs") {
if (is_ot_subtype("stairs", terrain_type)) {
if( const auto p = random_point( points_in_rectangle( { lw, tw, abs_sub.z }, { SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, abs_sub.z } ), [this]( const tripoint &n ) { return ter( n ) == t_rock_floor; } ) ) {
ter_set( *p, t_stairs_down );
}
Expand Down

0 comments on commit 56a2166

Please sign in to comment.