@ -1,23 +1,26 @@
# include "Debug.h"
# include "PluginManager.h"
# include "TileTypes.h"
# include "modules/Gui.h"
# include "modules/Gui.h"
# include "modules/Maps.h"
# include "modules/Maps.h"
# include "modules/Screen.h"
# include "modules/Screen.h"
# include "modules/Textures.h"
# include "modules/Textures.h"
# include "Debug.h"
# include "LuaTools.h"
# include "PluginManager.h"
# include "df/init.h"
# include "df/init.h"
# include "df/map_block.h"
# include "df/tile_designation.h"
# include <functional>
using namespace DFHack ;
using namespace DFHack ;
DFHACK_PLUGIN ( " pathable " ) ;
DFHACK_PLUGIN ( " pathable " ) ;
REQUIRE_GLOBAL ( gps ) ;
REQUIRE_GLOBAL ( init ) ;
REQUIRE_GLOBAL ( window_x ) ;
REQUIRE_GLOBAL ( window_x ) ;
REQUIRE_GLOBAL ( window_y ) ;
REQUIRE_GLOBAL ( window_y ) ;
REQUIRE_GLOBAL ( window_z ) ;
REQUIRE_GLOBAL ( window_z ) ;
REQUIRE_GLOBAL ( world ) ;
namespace DFHack {
namespace DFHack {
DBG_DECLARE ( pathable , log , DebugCategory : : LINFO ) ;
DBG_DECLARE ( pathable , log , DebugCategory : : LINFO ) ;
@ -31,7 +34,7 @@ DFhackCExport command_result plugin_shutdown(color_ostream &out) {
return CR_OK ;
return CR_OK ;
}
}
static void paintScreen ( df : : coord target , bool s kip_unrevealed = false ) {
static void paintScreen Pathable ( df : : coord target , bool s how_hidden = false ) {
DEBUG ( log ) . print ( " entering paintScreen \n " ) ;
DEBUG ( log ) . print ( " entering paintScreen \n " ) ;
bool use_graphics = Screen : : inGraphicsMode ( ) ;
bool use_graphics = Screen : : inGraphicsMode ( ) ;
@ -39,8 +42,8 @@ static void paintScreen(df::coord target, bool skip_unrevealed = false) {
int selected_tile_texpos = 0 ;
int selected_tile_texpos = 0 ;
Screen : : findGraphicsTile ( " CURSORS " , 4 , 3 , & selected_tile_texpos ) ;
Screen : : findGraphicsTile ( " CURSORS " , 4 , 3 , & selected_tile_texpos ) ;
long pathable_tile_texpos = df: : global : : init- > load_bar_texpos [ 1 ] ;
long pathable_tile_texpos = init- > load_bar_texpos [ 1 ] ;
long unpathable_tile_texpos = df: : global : : init- > load_bar_texpos [ 4 ] ;
long unpathable_tile_texpos = init- > load_bar_texpos [ 4 ] ;
long on_off_texpos = Textures : : getMapPathableTexposStart ( ) ;
long on_off_texpos = Textures : : getMapPathableTexposStart ( ) ;
if ( on_off_texpos > 0 ) {
if ( on_off_texpos > 0 ) {
pathable_tile_texpos = on_off_texpos + 0 ;
pathable_tile_texpos = on_off_texpos + 0 ;
@ -61,7 +64,7 @@ static void paintScreen(df::coord target, bool skip_unrevealed = false) {
continue ;
continue ;
}
}
if ( skip_unrevealed & & ! Maps : : isTileVisible ( map_pos ) ) {
if ( ! show_hidden & & ! Maps : : isTileVisible ( map_pos ) ) {
TRACE ( log ) . print ( " skipping hidden tile \n " ) ;
TRACE ( log ) . print ( " skipping hidden tile \n " ) ;
continue ;
continue ;
}
}
@ -110,7 +113,101 @@ static void paintScreen(df::coord target, bool skip_unrevealed = false) {
}
}
}
}
static bool is_warm ( const df : : coord & pos ) {
auto block = Maps : : getTileBlock ( pos ) ;
if ( ! block )
return false ;
return block - > temperature_1 [ pos . x & 15 ] [ pos . y & 15 ] > = 10075 ;
}
static bool is_rough_wall ( int16_t x , int16_t y , int16_t z ) {
df : : tiletype * tt = Maps : : getTileType ( x , y , z ) ;
if ( ! tt )
return false ;
return tileShape ( * tt ) = = df : : tiletype_shape : : WALL & &
tileSpecial ( * tt ) ! = df : : tiletype_special : : SMOOTH ;
}
static bool will_leak ( int16_t x , int16_t y , int16_t z ) {
auto des = Maps : : getTileDesignation ( x , y , z ) ;
if ( ! des )
return false ;
if ( des - > bits . liquid_type = = df : : tile_liquid : : Water & & des - > bits . flow_size > = 1 )
return true ;
if ( des - > bits . water_table & & is_rough_wall ( x , y , z ) )
return true ;
return false ;
}
static bool is_damp ( const df : : coord & pos ) {
return will_leak ( pos . x - 1 , pos . y - 1 , pos . z ) | |
will_leak ( pos . x , pos . y - 1 , pos . z ) | |
will_leak ( pos . x + 1 , pos . y - 1 , pos . z ) | |
will_leak ( pos . x - 1 , pos . y , pos . z ) | |
will_leak ( pos . x + 1 , pos . y , pos . z ) | |
will_leak ( pos . x - 1 , pos . y + 1 , pos . z ) | |
will_leak ( pos . x , pos . y + 1 , pos . z ) | |
will_leak ( pos . x + 1 , pos . y + 1 , pos . z ) ;
will_leak ( pos . x , pos . y + 1 , pos . z + 1 ) ;
}
static void paintScreenWarmDamp ( bool show_hidden = false ) {
DEBUG ( log ) . print ( " entering paintScreenDampWarm \n " ) ;
if ( Screen : : inGraphicsMode ( ) )
return ;
auto dims = Gui : : getDwarfmodeViewDims ( ) . map ( ) ;
for ( int y = dims . first . y ; y < = dims . second . y ; + + y ) {
for ( int x = dims . first . x ; x < = dims . second . x ; + + x ) {
df : : coord map_pos ( * window_x + x , * window_y + y , * window_z ) ;
if ( ! Maps : : isValidTilePos ( map_pos ) )
continue ;
if ( ! show_hidden & & ! Maps : : isTileVisible ( map_pos ) ) {
TRACE ( log ) . print ( " skipping hidden tile \n " ) ;
continue ;
}
TRACE ( log ) . print ( " scanning map tile at (%d, %d, %d) screen offset (%d, %d) \n " ,
map_pos . x , map_pos . y , map_pos . z , x , y ) ;
Screen : : Pen cur_tile = Screen : : readTile ( x , y , true ) ;
if ( ! cur_tile . valid ( ) ) {
DEBUG ( log ) . print ( " cannot read tile at offset %d, %d \n " , x , y ) ;
continue ;
}
int color = is_warm ( map_pos ) ? COLOR_RED : is_damp ( map_pos ) ? COLOR_BLUE : COLOR_BLACK ;
if ( color = = COLOR_BLACK ) {
TRACE ( log ) . print ( " skipping non-warm, non-damp tile \n " ) ;
continue ;
}
// this will also change the color of the cursor or any selection box that overlaps
// the tile. this is intentional since it makes the UI more readable
if ( cur_tile . fg & & cur_tile . ch ! = ' ' ) {
cur_tile . fg = color ;
cur_tile . bg = 0 ;
} else {
cur_tile . fg = 0 ;
cur_tile . bg = color ;
}
cur_tile . bold = false ;
if ( cur_tile . tile )
cur_tile . tile_mode = Screen : : Pen : : CharColor ;
Screen : : paintTile ( cur_tile , x , y , true ) ;
}
}
}
DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION ( paintScreen ) ,
DFHACK_LUA_FUNCTION ( paintScreenPathable ) ,
DFHACK_LUA_FUNCTION ( paintScreenWarmDamp ) ,
DFHACK_LUA_END
DFHACK_LUA_END
} ;
} ;