From 391a02218196eabd9fad3b8a2d6e32f9dc84e643 Mon Sep 17 00:00:00 2001 From: Christian Doczkal <20443222+chdoc@users.noreply.github.com> Date: Sun, 30 Aug 2026 11:13:23 +0200 Subject: [PATCH] fix detection of current weather --- docs/changelog.txt | 4 ++++ docs/dev/Lua API.rst | 10 +++++++++- library/LuaApi.cpp | 13 +++++++++++++ library/include/modules/Maps.h | 4 ++++ library/include/modules/World.h | 3 ++- library/modules/Maps.cpp | 23 +++++++++++++++++++++++ library/modules/World.cpp | 8 ++++---- 7 files changed, 59 insertions(+), 6 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index e07a76a521..85d44c173d 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -61,6 +61,8 @@ Template for new versions: ## Fixes +- Fix broken weather lookup in ``World::ReadCurrentWeather`` + ## Misc Improvements ## Documentation @@ -70,6 +72,8 @@ Template for new versions: - Added ``Maps::getSiteTypeName`` to print the sites classification as a string (e.g. "mountain halls") - Added ``Maps::addRegionBiomeOffset`` to shift world region coordinate by region_details biome reference - Added ``Maps::describeSurroundings`` to get surroundings classification from savagery and evilness +- Added ``Maps::getCurrentWeather`` to determine the current weather on the map. +- Deprecated ``World::ReadCurrentWeather`` in favor of ``Maps::getCurrentWeather`` ## Lua diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index e8a1cd9f67..25d96d516e 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -2342,7 +2342,8 @@ World module * ``dfhack.world.ReadCurrentWeather()`` - Returns the current game weather (``df.weather_type``). + Returns the current game weather (``df.weather_type``). Deprecated: use + ``dfhack.maps.getCurrentWeather()`` instead. * ``dfhack.world.SetCurrentWeather(weather)`` @@ -2441,6 +2442,13 @@ Maps module Returns *x, y* for use with ``getRegionBiome`` and ``getBiomeType``. +* ``dfhack.maps.getCurrentWeather(coords)`` + ``dfhack.maps.getCurrentWeather(x,y,z)`` + ``dfhack.maps.getCurrentWeather()`` + + Returns the current game weather (``df.weather_type``) at the specified tile + or at the center of the map if no argument is provided. + * ``dfhack.maps.getPlantAtTile(pos)``, or ``getPlantAtTile(x,y,z)`` Returns the plant struct that owns the tile at the specified position. diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 6a08756156..6a9ee20bf6 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2724,6 +2724,18 @@ static int maps_getTileBiomeRgn(lua_State *L) return Lua::PushPosXY(L, Maps::getTileBiomeRgn(pos)); } +static int maps_getCurrentWeather(lua_State *L) +{ + if (lua_gettop(L) == 0) + { + lua_pushinteger(L, Maps::getCurrentWeather()); + } else { + auto pos = CheckCoordXYZ(L, 1, true); + lua_pushinteger(L, Maps::getCurrentWeather(pos)); + } + return 1; +} + static int maps_getPlantAtTile(lua_State *L) { auto pos = CheckCoordXYZ(L, 1, true); @@ -2830,6 +2842,7 @@ static const luaL_Reg dfhack_maps_funcs[] = { { "getTileFlags", maps_getTileFlags }, { "getRegionBiome", maps_getRegionBiome }, { "getTileBiomeRgn", maps_getTileBiomeRgn }, + { "getCurrentWeather", maps_getCurrentWeather }, { "getPlantAtTile", maps_getPlantAtTile }, { "getBiomeType", maps_getBiomeType }, { "isTileAquifer", maps_isTileAquifer }, diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index 4a77d08ae2..2575bdf585 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -44,6 +44,7 @@ distribution. #include "df/matter_state.h" #include "df/tile_dig_designation.h" #include "df/tiletype.h" +#include "df/weather_type.h" #include "df/world_site.h" namespace df { @@ -365,6 +366,9 @@ DFHACK_EXPORT df::coord2d getBlockTileBiomeRgn(df::map_block *block, df::coord2d inline df::coord2d getTileBiomeRgn(df::coord pos) { return getBlockTileBiomeRgn(getTileBlock(pos), pos); } +DFHACK_EXPORT df::weather_type getCurrentWeather(df::coord pos); +DFHACK_EXPORT df::weather_type getCurrentWeather(); + // Enables per-frame updates for liquid flow and/or temperature. DFHACK_EXPORT void enableBlockUpdates(df::map_block *blk, bool flow = false, bool temperature = false); diff --git a/library/include/modules/World.h b/library/include/modules/World.h index 46b8f2e351..6d84df6f0c 100644 --- a/library/include/modules/World.h +++ b/library/include/modules/World.h @@ -39,6 +39,7 @@ distribution. #include "df/game_mode.h" #include "df/game_type.h" #include "df/unit.h" +#include "df/weather_type.h" namespace df @@ -80,7 +81,7 @@ namespace DFHack DFHACK_EXPORT uint32_t ReadCurrentYear(); DFHACK_EXPORT uint32_t ReadCurrentMonth(); DFHACK_EXPORT uint32_t ReadCurrentDay(); - DFHACK_EXPORT uint8_t ReadCurrentWeather(); + DFHACK_EXPORT df::weather_type ReadCurrentWeather(); // deprecated DFHACK_EXPORT void SetCurrentWeather(uint8_t weather); DFHACK_EXPORT bool ReadGameMode(t_gamemodes& rd); DFHACK_EXPORT bool WriteGameMode(const t_gamemodes & wr); // this is very dangerous diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 95ab00b2d7..bdbb67a69a 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -67,6 +67,7 @@ distribution. #include "df/plotinfost.h" #include "df/region_map_entry.h" #include "df/site_map_infost.h" +#include "df/weather_type.h" #include "df/world_data.h" #include "df/world_geo_biome.h" #include "df/world_geo_layer.h" @@ -989,6 +990,28 @@ df::coord2d Maps::getBlockTileBiomeRgn(df::map_block *block, df::coord2d pos) return df::coord2d(); } +df::weather_type Maps::getCurrentWeather(df::coord pos) +{ + if (df::global::current_weather){ + auto &map = world->map; + auto [biome_x, biome_y] = Maps::getTileBiomeRgn(pos); + const int weather_x = biome_x - map.region_x / 16 + 1; + const int weather_y = biome_y - map.region_y / 16 + 1; + return (*df::global::current_weather)[weather_x][weather_y]; + } + return df::weather_type::None; +} + +df::weather_type Maps::getCurrentWeather() +{ + auto &map = world->map; + if (map.x_count > 0 && map.y_count > 0 && map.z_count > 0) { + return Maps::getCurrentWeather(df::coord( map.x_count / 2, map.y_count / 2, map.z_count / 2 )); + } else { + return df::weather_type::None; + } +} + /* * Layer geology */ diff --git a/library/modules/World.cpp b/library/modules/World.cpp index d19f61fcee..c0c6d590fd 100644 --- a/library/modules/World.cpp +++ b/library/modules/World.cpp @@ -29,6 +29,7 @@ distribution. #include "modules/Gui.h" #include "modules/Translation.h" #include "modules/Units.h" +#include "modules/Maps.h" #include "modules/World.h" #include "modules/Translation.h" @@ -37,6 +38,7 @@ distribution. #include "df/map_block.h" #include "df/plotinfost.h" #include "df/viewscreen_dwarfmodest.h" +#include "df/weather_type.h" #include "df/world.h" #include "df/world_data.h" #include "df/world_site.h" @@ -153,11 +155,9 @@ uint32_t World::ReadCurrentDay() return ((ReadCurrentTick() / 1200) % 28) + 1; } -uint8_t World::ReadCurrentWeather() +df::weather_type World::ReadCurrentWeather() { - if (df::global::current_weather) - return (*df::global::current_weather)[2][2]; - return 0; + return Maps::getCurrentWeather(); } void World::SetCurrentWeather(uint8_t weather)