Skip to content

Commit

Permalink
Adds priority parameter for special placement (CleverRaven#68389)
Browse files Browse the repository at this point in the history
* Adds priority parameter for special placement

* document

* clang error

* warning
  • Loading branch information
lispcoc authored and detahramet committed Nov 6, 2023
1 parent 631e8b8 commit 23346de
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 22 deletions.
1 change: 1 addition & 0 deletions doc/OVERMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ original intersection.
| `city_distance` | Min/max distance from a city edge that the special may be placed. Use -1 for unbounded. |
| `city_sizes` | Min/max city size for a city that the special may be placed near. Use -1 for unbounded. |
| `occurrences` | Min/max number of occurrences when placing the special. If UNIQUE flag is set, becomes X of Y chance. |
| `priority` | **Warning: Do not use this unnecessarily.** The generation process is executed in the order of specials with the highest value. Can be used when maps are difficult to generate. (large maps, maps that are or require dependencies etc) It is **strongly recommended** to set it to 1 (HIGH priority) or -1 (LOW priority) if used. (default = 0) |
| `flags` | See `Overmap specials` in [JSON_FLAGS.md](JSON_FLAGS.md). |
| `rotate` | Whether the special can rotate. True if not specified. |

Expand Down
4 changes: 4 additions & 0 deletions src/omdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ class overmap_special
return flags_;
}
bool has_flag( const std::string & ) const;
int get_priority() const {
return priority_;
}
int longest_side() const;
std::vector<overmap_special_terrain> preview_terrains() const;
std::vector<overmap_special_locations> required_locations() const;
Expand Down Expand Up @@ -578,6 +581,7 @@ class overmap_special
bool rotatable_ = true;
overmap_special_spawns monster_spawns_;
cata::flat_set<std::string> flags_;
int priority_ = 0;

// These locations are the default values if ones are not specified for the individual OMTs.
cata::flat_set<string_id<overmap_location>> default_locations_;
Expand Down
54 changes: 32 additions & 22 deletions src/overmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2773,6 +2773,7 @@ void overmap_special::load( const JsonObject &jo, const std::string &src )

assign( jo, "city_sizes", constraints_.city_size, strict );
assign( jo, "city_distance", constraints_.city_distance, strict );
assign( jo, "priority", priority_, strict );
}

assign( jo, "spawns", monster_spawns_, strict );
Expand Down Expand Up @@ -6296,31 +6297,40 @@ bool overmap::place_special_attempt(
const city &nearest_city = get_nearest_city( p );

std::shuffle( enabled_specials.begin(), enabled_specials.end(), rng_get_engine() );
for( auto iter = enabled_specials.begin(); iter != enabled_specials.end(); ++iter ) {
const overmap_special &special = *iter->special_details;
const overmap_special_placement_constraints &constraints = special.get_constraints();
// If we haven't finished placing minimum instances of all specials,
// skip specials that are at their minimum count already.
if( !place_optional && iter->instances_placed >= constraints.occurrences.min ) {
continue;
}
// City check is the fastest => it goes first.
if( !special.can_belong_to_city( p, nearest_city ) ) {
continue;
}
// See if we can actually place the special there.
const om_direction::type rotation = random_special_rotation( special, p, must_be_unexplored );
if( rotation == om_direction::type::invalid ) {
continue;
}
std::set<int> priorities;
for( const overmap_special_placement &os : enabled_specials ) {
priorities.emplace( os.special_details->get_priority() );
}
for( auto pri_iter = priorities.rbegin(); pri_iter != priorities.rend(); ++pri_iter ) {
for( auto iter = enabled_specials.begin(); iter != enabled_specials.end(); ++iter ) {
const overmap_special &special = *iter->special_details;
if( *pri_iter != special.get_priority() ) {
continue;
}
const overmap_special_placement_constraints &constraints = special.get_constraints();
// If we haven't finished placing minimum instances of all specials,
// skip specials that are at their minimum count already.
if( !place_optional && iter->instances_placed >= constraints.occurrences.min ) {
continue;
}
// City check is the fastest => it goes first.
if( !special.can_belong_to_city( p, nearest_city ) ) {
continue;
}
// See if we can actually place the special there.
const om_direction::type rotation = random_special_rotation( special, p, must_be_unexplored );
if( rotation == om_direction::type::invalid ) {
continue;
}

place_special( special, p, rotation, nearest_city, false, must_be_unexplored );
place_special( special, p, rotation, nearest_city, false, must_be_unexplored );

if( ++iter->instances_placed >= constraints.occurrences.max ) {
enabled_specials.erase( iter );
}
if( ++iter->instances_placed >= constraints.occurrences.max ) {
enabled_specials.erase( iter );
}

return true;
return true;
}
}

return false;
Expand Down

0 comments on commit 23346de

Please sign in to comment.