@ -5,6 +5,7 @@
# include <vector>
# include "Core.h"
# include "LuaTools.h"
# include <Console.h>
# include <Export.h>
# include <PluginManager.h>
@ -504,7 +505,7 @@ static bool find_anchor_in_spiral(const df::coord &start)
return found ;
}
static bool find_valid_building_sites ( bool in_future_placement_mode )
static bool find_valid_building_sites ( bool in_future_placement_mode , bool use_buildingplan )
{
valid_building_sites . clear ( ) ;
open_air_sites . clear ( ) ;
@ -519,7 +520,8 @@ static bool find_valid_building_sites(bool in_future_placement_mode)
continue ;
building_site site ( df : : coord ( xB , yB , box_second . z ) , false ) ;
if ( is_valid_building_site ( site , false , true , in_future_placement_mode ) )
// if we're using buildingplan, it will take care of filtering out bad tiles
if ( use_buildingplan | | is_valid_building_site ( site , false , true , in_future_placement_mode ) )
valid_building_sites . push_back ( site ) ;
else if ( site . in_open_air )
{
@ -531,25 +533,115 @@ static bool find_valid_building_sites(bool in_future_placement_mode)
}
}
size_t last_open_air_count = 0 ;
while ( valid_building_sites . size ( ) > 0 & & open_air_sites . size ( ) ! = last_open_air_count )
if ( ! use_buildingplan )
{
last_open_air_count = open_air_sites . size ( ) ;
deque < building_site > current_open_air_list = open_air_sites ;
open_air_sites . clear ( ) ;
for ( deque < building_site > : : iterator it = current_open_air_list . begin ( ) ; it ! = current_open_air_list . end ( ) ; it + + )
size_t last_open_air_count = 0 ;
while ( valid_building_sites . size ( ) > 0 & & open_air_sites . size ( ) ! = last_open_air_count )
{
if ( is_orthogonal_to_pending_construction ( * it ) )
valid_building_sites . push_back ( * it ) ;
else
open_air_sites . push_back ( * it ) ;
}
last_open_air_count = open_air_sites . size ( ) ;
deque < building_site > current_open_air_list = open_air_sites ;
open_air_sites . clear ( ) ;
for ( deque < building_site > : : iterator it = current_open_air_list . begin ( ) ; it ! = current_open_air_list . end ( ) ; it + + )
{
if ( is_orthogonal_to_pending_construction ( * it ) )
valid_building_sites . push_back ( * it ) ;
else
open_air_sites . push_back ( * it ) ;
}
}
}
return valid_building_sites . size ( ) > 0 ;
}
static bool is_buildingplan_enabled ( )
{
auto L = Lua : : Core : : State ;
color_ostream_proxy out ( Core : : getInstance ( ) . getConsole ( ) ) ;
Lua : : StackUnwinder top ( L ) ;
if ( ! ( lua_checkstack ( L , 1 ) & &
Lua : : PushModulePublic ( out , L , " plugins.buildingplan " , " isEnabled " ) & &
Lua : : SafeCall ( out , L , 0 , 1 ) ) )
{
return false ;
}
return lua_toboolean ( L , - 1 ) ;
}
static bool is_buildingplan_planmode_enabled (
df : : building_type type , int16_t subtype , int32_t custom )
{
auto L = Lua : : Core : : State ;
color_ostream_proxy out ( Core : : getInstance ( ) . getConsole ( ) ) ;
Lua : : StackUnwinder top ( L ) ;
if ( ! lua_checkstack ( L , 4 ) | |
! Lua : : PushModulePublic (
out , L , " plugins.buildingplan " , " isPlanModeEnabled " ) )
return false ;
Lua : : Push ( L , type ) ;
Lua : : Push ( L , subtype ) ;
Lua : : Push ( L , custom ) ;
if ( ! Lua : : SafeCall ( out , L , 3 , 1 ) )
return false ;
return lua_toboolean ( L , - 1 ) ;
}
static bool is_buildingplan_managed ( )
{
return is_buildingplan_enabled ( ) & &
is_buildingplan_planmode_enabled ( ui_build_selector - > building_type ,
ui_build_selector - > building_subtype ,
ui_build_selector - > custom_type ) ;
}
static bool build_with_buildingplan_box_select ( const df : : coord & pos )
{
auto L = Lua : : Core : : State ;
color_ostream_proxy out ( Core : : getInstance ( ) . getConsole ( ) ) ;
CoreSuspendClaimer suspend ;
Lua : : StackUnwinder top ( L ) ;
if ( ! lua_checkstack ( L , 5 ) | |
! Lua : : PushModulePublic (
out , L , " plugins.automaterial " ,
" build_with_buildingplan_box_select " ) )
{
return false ;
}
Lua : : Push ( L , ui_build_selector - > building_subtype ) ;
Lua : : Push ( L , pos . x ) ;
Lua : : Push ( L , pos . y ) ;
Lua : : Push ( L , pos . z ) ;
if ( ! Lua : : SafeCall ( out , L , 4 , 1 ) )
return false ;
return lua_toboolean ( L , - 1 ) ;
}
static bool build_with_buildingplan_ui ( )
{
auto L = Lua : : Core : : State ;
color_ostream_proxy out ( Core : : getInstance ( ) . getConsole ( ) ) ;
CoreSuspendClaimer suspend ;
Lua : : StackUnwinder top ( L ) ;
return lua_checkstack ( L , 1 ) & &
Lua : : PushModulePublic ( out , L , " plugins.automaterial " ,
" build_with_buildingplan_ui " ) & &
Lua : : SafeCall ( out , L , 0 , 1 ) ;
}
static bool designate_new_construction ( df : : coord & pos , df : : construction_type & type , df : : item * item )
{
auto newinst = Buildings : : allocInstance ( pos , building_type : : Construction , type ) ;
@ -722,11 +814,13 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
}
else if ( in_placement_stage ( ) )
{
if ( input - > count ( interface_key : : CUSTOM_A ) )
bool use_buildingplan = is_buildingplan_managed ( ) ;
if ( ! use_buildingplan & & input - > count ( interface_key : : CUSTOM_A ) )
{
auto_choose_materials = ! auto_choose_materials ;
}
else if ( input - > count ( interface_key : : CUSTOM_T ) )
else if ( ! use_buildingplan & & input - > count ( interface_key : : CUSTOM_T ) )
{
revert_to_last_used_type = ! revert_to_last_used_type ;
}
@ -739,7 +833,7 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
return ;
}
else if ( input - > count ( interface_key : : CUSTOM_O ) )
else if ( ! use_buildingplan & & input - > count ( interface_key : : CUSTOM_O ) )
{
allow_future_placement = ! allow_future_placement ;
}
@ -816,6 +910,15 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
return ;
}
}
else if ( use_buildingplan
& & ui_build_selector - > errors . size ( ) = = 0
& & input - > count ( interface_key : : SELECT ) )
{
build_with_buildingplan_ui ( ) ;
Gui : : refreshSidebar ( ) ;
input - > clear ( ) ;
return ;
}
}
}
//END UI Methods
@ -876,16 +979,17 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
static bool saved_revert_setting = false ;
static bool auto_select_applied = false ;
bool use_buildingplan = is_buildingplan_managed ( ) ;
box_select_mode = SELECT_MATERIALS ;
if ( new_start )
{
bool ok_to_continue = false ;
bool in_future_placement_mode = false ;
if ( ! find_valid_building_sites ( false ))
if ( ! find_valid_building_sites ( false , use_buildingplan ))
{
if ( allow_future_placement )
{
in_future_placement_mode = find_valid_building_sites ( true );
in_future_placement_mode = find_valid_building_sites ( true , use_buildingplan );
}
}
else
@ -893,7 +997,8 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
ok_to_continue = true ;
}
if ( in_future_placement_mode )
// if using buildingplan, we don't need an anchor
if ( ! use_buildingplan & & in_future_placement_mode )
{
ok_to_continue = find_anchor_in_spiral ( valid_building_sites [ 0 ] . pos ) ;
}
@ -924,6 +1029,15 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
{
building_site site = valid_building_sites . front ( ) ;
valid_building_sites . pop_front ( ) ;
if ( use_buildingplan )
{
// we don't actually care if this fails. buildingplan will return
// false when it filters out bad tiles, and that's ok.
build_with_buildingplan_box_select ( site . pos ) ;
continue ;
}
if ( box_select_materials . size ( ) > 0 )
{
df : : construction_type type = ( df : : construction_type ) ui_build_selector - > building_subtype ;
@ -986,8 +1100,10 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
// Allocation done, reset
move_cursor ( box_second ) ;
// if we're using buildingplan, we never actually leave the placement
// screen, so there's no need to re-enter the screen
revert_to_last_used_type = saved_revert_setting ;
if ( ! revert_to_last_used_type )
if ( ! use_buildingplan & & ! revert_to_last_used_type)
{
send_key ( df : : interface_key : : LEAVESCREEN ) ;
}
@ -1091,9 +1207,18 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
}
else if ( in_placement_stage ( ) & & ui_build_selector - > building_subtype < 7 )
{
OutputString ( COLOR_BROWN , x , y , " DFHack Options " , true , left_margin ) ;
AMOutputToggleString ( x , y , " Auto Mat-select " , " a " , auto_choose_materials , true , left_margin ) ;
AMOutputToggleString ( x , y , " Reselect Type " , " t " , revert_to_last_used_type , true , left_margin ) ;
bool use_buildingplan = is_buildingplan_managed ( ) ;
OutputString ( COLOR_BROWN , x , y , " DFHack Automaterial Options " , true , left_margin ) ;
if ( use_buildingplan )
{
y + = 2 ;
}
else
{
AMOutputToggleString ( x , y , " Auto Mat-select " , " a " , auto_choose_materials , true , left_margin ) ;
AMOutputToggleString ( x , y , " Reselect Type " , " t " , revert_to_last_used_type , true , left_margin ) ;
}
+ + y ;
AMOutputToggleString ( x , y , " Box Select " , " b " , box_select_enabled , true , left_margin ) ;
@ -1101,9 +1226,20 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
{
AMOutputToggleString ( x , y , " Show Box Mask " , " x " , show_box_selection , true , left_margin ) ;
OutputHotkeyString ( x , y , ( hollow_selection ) ? " Make Solid " : " Make Hollow " , " h " , true , left_margin ) ;
AMOutputToggleString ( x , y , " Open Placement " , " o " , allow_future_placement , true , left_margin ) ;
if ( use_buildingplan )
+ + y ;
else
AMOutputToggleString ( x , y , " Open Placement " , " o " , allow_future_placement , true , left_margin ) ;
}
+ + y ;
else
{
y + = 3 ;
}
y + = 2 ;
if ( is_buildingplan_enabled ( ) )
OutputString ( COLOR_BROWN , x , y , " DFHack Buildingplan Options " , true , left_margin ) ;
if ( box_select_enabled )
{
Screen : : Pen pen ( ' ' , COLOR_BLACK ) ;