Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find or create overmap special after overmap generation #27142

Conversation

ralreegorganon
Copy link
Contributor

Summary

SUMMARY: Interface "Find or create overmap special after overmap generation"

Purpose of change

This series of changes enables finding and creating overmap specials after overmap generation has been completed. The initial use of this will be in JSONizing mission starts, to be used by the infrastructure added in #27037. Additionally, it makes the debug placement of overmap specials behave more like the placement during overmap generation.

Describe the solution

This is accomplished through a handful of inter-related infrastructure changes documented in their individual commits, but generally speaking this:

  1. Adds new functions to overmap and overmapbuffer to allow determining whether or not a given overmap terrain has been explored and had mapgen run on it
  2. Updates overmap special placement and associated overmap connection simple pathfinding to allow specifying whether or not a location must be unexplored when evaluating it for placement
  3. Updates the overmap terrain "find" methods on overmapbuffer to allow specifying that a given overmap terrain must be part of a given special to be considered a match
  4. Adds place_special methods to overmapbuffer to allow it to either unconditionally place a special at a specified location and rotation, or place a special using the existing overmap special placement algorithm (with the ability to leverage the aforementioned infrastructure changes so the placement happens out of the player's explored areas)
  5. Uses the previous changes to update the debug placement of overmap specials to behave more like those placed during overmap generation (e.g. record special -> omt association, generate road connections)
  6. Uses the previous changes in mission_start::reveal_refugee_center to make it overmap special aware, so that it will consider the special when searching for the refugee center, and will create it if it can't find it.

Describe alternatives you've considered

This set of changes stops short of reworking the entirety of mission_start to utilize these changes where appropriate; that is an in-progress follow up effort.

There are some deficiencies in overmap special placement as it relates to placement done after overmap generation versus during overmap generation (specifically around the overmap connections and subterranean locations) which can be iterated on in future work--things like lab creation, sewer and subway creation, and their associated connections all have a second pass that happens after the specials are placed during overmap generation, but that doesn't occur here.

Additional context

This doesn't wildly change the actual overmap special placement algorithm, so when specials are placed after the fact, they suffer from all limitations it currently has, plus the additional limitations of being restricted in where it can place things due to not considering areas that have already been explored, plus all of the existing specials taking up space.

To mitigate this some, I allowed the "overmap special frequency" to be based on the size of the special being placed rather than fixed at the constant value used during overmap generation. This effectively means that smaller specials have more possible locations and thus a better chance at being placed.

In my testing, this has worked out well enough, and the actual biggest factor in how successful it will be in placing the special is how restrictive the criteria for a special are. A city size 16, spacing 0 world with a special that is large, has subterranean entries, requires existing overmap connections, must be placed an exact distance from a city, and which has restrictive allowed terrains will always be difficult to place.

I also don't think this set of changes precludes us revisiting "mandatory" specials for missions and having those be included during overmap generation, preempting all the other special placements.

For testing, an easy test is to edit specials.json and set the occurrences for the evac_center special to "occurrences" : [0, 0],, and then use the evac computer's "Contact Us" entry.

Finally, a quick before/after screenshot of the test case above where the evac center doesn't exist until we try and locate it in using the computer.

large-animated

And zoomed in on the local area that actually changed...

small-animated

@ZhilkinSerg ZhilkinSerg added Missions Quests and missions Map / Mapgen Overmap, Mapgen, Map extras, Map display [C++] Changes (can be) made in C++. Previously named `Code` labels Dec 17, 2018
src/overmap.cpp Outdated
return false;
}

const bool is_generated = MAPBUFFER.lookup_submap( omt_to_sm_copy( loc ) ) != nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not match. inbounds above takes local coordinates, but MAPBUFFER::lookup_submap requires a global variable. You need to add overmap::loc (converted to the correct coordinate system).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Thanks for catching that.

const tripoint s_loc( origin.x + dist - i, origin.y + dist, z );
if( is_findable_location( s_loc, type, must_be_seen, allow_subtype_matches, existing_overmaps_only,
om_special ) ) {
return tripoint( s_loc );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return tripoint( s_loc );
return s_loc;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I had done it correctly for the first entry (n_loc)--just an oversight to have not done it for the other three.

const tripoint w_loc( origin.x - dist, origin.y + dist - i, z );
if( is_findable_location( w_loc, type, must_be_seen, allow_subtype_matches, existing_overmaps_only,
om_special ) ) {
return tripoint( w_loc );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here and below with e_loc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done as noted above.

for( const auto &special_placement : batch ) {
if( special_placement.instances_placed > 0 ) {
// It was placed, lets get outta here.
placed = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can return true from here instead of using the variable placed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@ralreegorganon ralreegorganon force-pushed the find-or-create-overmap-special-after-mapgen branch from 546314a to 4c6e9d8 Compare December 17, 2018 20:23

// We couldn't find the special, so let's try and place it.
if( center_pos == overmap::invalid_tripoint ) {
bool placed = overmap_buffer.place_special( os_evac_center, your_pos, OMAPX * 5 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be const.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@ZhilkinSerg ZhilkinSerg self-assigned this Dec 18, 2018
Adds a new struct which contains a pointer to an overmap and a
tripoint local to the overmap.

Added new methods for getting an overmap with coordinates projected
to the local coordinate system when provided with a global overmap
terrain tripoint coordinate. Has both get_ and get_existing varieties.
Add new methods to overmap and overmap buffer to allow checking
whether or not a given overmap terrain location has been generated,
which can be used to inform code that wants to change the overmap but
only wants to do so if the location hasn't been generated already.
…plored

Also allow forcing placement of overmap special even when it doesn't
meet criteria (primarily to be used in the debug menu placement of
overmap specials).
Allows for placement of a specific special at a specified location and
orientation, or simply specifying a special to be placed and deferring
placement to the overmap's placement algorithm.
This brings debug placement more in line with the placement done during
map generation, e.g. it will make connections, record placement into the
data structure tying overmap terrains to the special that placed them,
and so on.
@ralreegorganon ralreegorganon force-pushed the find-or-create-overmap-special-after-mapgen branch from 4c6e9d8 to 3828433 Compare December 19, 2018 05:43
@ZhilkinSerg ZhilkinSerg merged commit 3b7a52e into CleverRaven:master Dec 19, 2018
@ZhilkinSerg ZhilkinSerg removed their assignment Dec 19, 2018
@ralreegorganon ralreegorganon deleted the find-or-create-overmap-special-after-mapgen branch April 7, 2020 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[C++] Changes (can be) made in C++. Previously named `Code` Map / Mapgen Overmap, Mapgen, Map extras, Map display Missions Quests and missions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants