diff --git a/docs/changelog.txt b/docs/changelog.txt index abd1b845fc..443c5c0ef6 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -78,6 +78,8 @@ Template for new versions: - ``Random`` module: added ``SplitmixRNG`` class, implements the Splitmix64 RNG used by Dwarf Fortress for "simple" randomness - ``Items::getDescription``: fixed display of quality levels, now displays ALL item designations (in correct order) and obeys vanilla SHOW_IMP_QUALITY setting - ``cuboid::forCoord``, ``Maps::forCoord``: take additional parameter to control whether iteration goes in column major or row major order +- ``SC_NEW_MAP_AVAILABLE`` introduced to allow callbacks when moving between map tiles in adventure mode +- ``World::GetCurrentSiteIdsWithExtraRange`` added to check for valid sites with added range when in adventure mode ## Lua - ``script-manager``: new ``get_active_mods()`` function for getting information on active mods diff --git a/library/Core.cpp b/library/Core.cpp index 1208650579..fd1c4b7813 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -595,6 +595,7 @@ static void sc_event_map_init() { insert(SC_VIEWSCREEN_CHANGED); insert(SC_PAUSED); insert(SC_UNPAUSED); + insert(SC_NEW_MAP_AVAILABLE); #undef insert } } @@ -2044,8 +2045,11 @@ void Core::doUpdate(color_ostream &out) onStateChange(out, SC_MAP_UNLOADED); // and if the world is appearing, we report map change after that onStateChange(out, new_wdata ? SC_WORLD_LOADED : SC_WORLD_UNLOADED); - if(isMapLoaded()) + if (isMapLoaded()) + { onStateChange(out, SC_MAP_LOADED); + onStateChange(out, SC_NEW_MAP_AVAILABLE); + } } // otherwise just check for map change... else if (new_mapdata != last_local_map_ptr) @@ -2057,6 +2061,10 @@ void Core::doUpdate(color_ostream &out) { onStateChange(out, new_mapdata ? SC_MAP_LOADED : SC_MAP_UNLOADED); } + if (isMapLoaded()) + { + onStateChange(out, SC_NEW_MAP_AVAILABLE); + } } if (vs_changed) diff --git a/library/include/CoreDefs.h b/library/include/CoreDefs.h index dd78649394..87cf5da8e7 100644 --- a/library/include/CoreDefs.h +++ b/library/include/CoreDefs.h @@ -30,7 +30,8 @@ namespace DFHack SC_CORE_INITIALIZED = 5, SC_BEGIN_UNLOAD = 6, SC_PAUSED = 7, - SC_UNPAUSED = 8 + SC_UNPAUSED = 8, + SC_NEW_MAP_AVAILABLE = 9 }; } diff --git a/library/include/modules/World.h b/library/include/modules/World.h index b03170b5fa..92ade22858 100644 --- a/library/include/modules/World.h +++ b/library/include/modules/World.h @@ -92,6 +92,7 @@ namespace DFHack DFHACK_EXPORT df::unit * getAdventurer(); DFHACK_EXPORT int32_t GetCurrentSiteId(); + DFHACK_EXPORT void GetCurrentSiteIdsWithExtraRange(std::vector& ids, const int32_t x_range = 0, const int32_t y_range = 0, const uint32_t max = UINT_MAX); DFHACK_EXPORT bool IsSiteLoaded(); // Store DFHack tool data in the game save directory. diff --git a/library/modules/World.cpp b/library/modules/World.cpp index b41c625f17..65f304f798 100644 --- a/library/modules/World.cpp +++ b/library/modules/World.cpp @@ -240,6 +240,35 @@ int32_t World::GetCurrentSiteId() { return -1; } +void World::GetCurrentSiteIdsWithExtraRange(std::vector& ids, const int32_t x_range, const int32_t y_range, const uint32_t max) +{ + ids.clear(); + if (!plotinfo || max < 1) + { + return; + } + if (isFortressMode()) + { + ids.push_back(plotinfo->site_id); + } + if (auto adv = getAdventurer(); adv && world->world_data) { + auto& world_map = world->map; + auto adv_pos = Units::getPosition(adv); + df::coord2d rgn_pos(world_map.region_x + adv_pos.x / 48, world_map.region_y + adv_pos.y / 48); + for (auto site : world->world_data->sites) { + if (rgn_pos.x + x_range >= site->global_min_x && rgn_pos.x - x_range <= site->global_max_x + && rgn_pos.y + y_range >= site->global_min_y && rgn_pos.y - y_range <= site->global_max_y) + { + ids.push_back(site->id); + if (ids.size() >= max) + { + return; + } + } + } + } +} + bool World::IsSiteLoaded() { return GetCurrentSiteId() != -1; }