@ -30,8 +30,10 @@ static map<std::string, int32_t> registeredBuildings;
const int32_t OUTSIDE_ONLY = 1 ;
const int32_t OUTSIDE_ONLY = 1 ;
const int32_t EITHER = 0 ;
const int32_t EITHER = 0 ;
const int32_t INSIDE_ONLY = - 1 ;
const int32_t INSIDE_ONLY = - 1 ;
int32_t checkEvery = - 1 ;
void buildingCreated ( color_ostream & out , void * data ) ;
void buildingCreated ( color_ostream & out , void * data ) ;
void checkBuildings ( color_ostream & out , void * data ) ;
command_result outsideOnly ( color_ostream & out , vector < string > & parameters ) ;
command_result outsideOnly ( color_ostream & out , vector < string > & parameters ) ;
DFhackCExport command_result plugin_init ( color_ostream & out , std : : vector < PluginCommand > & commands )
DFhackCExport command_result plugin_init ( color_ostream & out , std : : vector < PluginCommand > & commands )
@ -44,6 +46,8 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug
" registers [custom building name] as inside-only \n "
" registers [custom building name] as inside-only \n "
" outsideOnly either [custom building name] \n "
" outsideOnly either [custom building name] \n "
" unregisters [custom building name] \n "
" unregisters [custom building name] \n "
" outsideOnly checkEvery [n] \n "
" checks for buildings that were previously in appropriate inside/outsideness but are not anymore every [n] ticks. If [n] is negative, disables checking. \n "
" outsideOnly clear \n "
" outsideOnly clear \n "
" unregisters all custom buildings \n "
" unregisters all custom buildings \n "
" enable outsideOnly \n "
" enable outsideOnly \n "
@ -63,7 +67,7 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug
DFhackCExport command_result plugin_onstatechange ( color_ostream & out , state_change_event event )
DFhackCExport command_result plugin_onstatechange ( color_ostream & out , state_change_event event )
{
{
switch ( event ) {
switch ( event ) {
case SC_ GAME _UNLOADED:
case SC_ WORLD _UNLOADED:
registeredBuildings . clear ( ) ;
registeredBuildings . clear ( ) ;
break ;
break ;
default :
default :
@ -76,14 +80,61 @@ DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) {
if ( enabled = = enable )
if ( enabled = = enable )
return CR_OK ;
return CR_OK ;
enabled = enable ;
enabled = enable ;
EventManager : : unregisterAll ( plugin_self ) ;
if ( enabled ) {
if ( enabled ) {
EventManager : : EventHandler handler ( buildingCreated , 1 ) ;
EventManager : : EventHandler handler ( buildingCreated , 1 ) ;
EventManager : : registerListener ( EventManager : : EventType : : BUILDING , handler , plugin_self ) ;
EventManager : : registerListener ( EventManager : : EventType : : BUILDING , handler , plugin_self ) ;
checkBuildings ( out , 0 ) ;
}
return CR_OK ;
}
void destroy ( df : : building * building ) {
if ( Buildings : : deconstruct ( building ) )
return ;
building - > flags . bits . almost_deleted = 1 ;
}
void checkBuildings ( color_ostream & out , void * data ) {
if ( ! enabled )
return ;
std : : vector < df : : building * > & buildings = df : : global : : world - > buildings . all ;
for ( size_t a = 0 ; a < buildings . size ( ) ; a + + ) {
df : : building * building = buildings [ a ] ;
if ( building = = NULL )
continue ;
if ( building - > getCustomType ( ) < 0 )
continue ;
df : : coord pos ( building - > centerx , building - > centery , building - > z ) ;
df : : tile_designation * des = Maps : : getTileDesignation ( pos ) ;
bool outside = des - > bits . outside ;
df : : building_def * def = df : : global : : world - > raws . buildings . all [ building - > getCustomType ( ) ] ;
int32_t type = registeredBuildings [ def - > code ] ;
if ( type = = EITHER ) {
registeredBuildings . erase ( def - > code ) ;
} else if ( type = = OUTSIDE_ONLY ) {
if ( outside )
continue ;
destroy ( building ) ;
} else if ( type = = INSIDE_ONLY ) {
if ( ! outside )
continue ;
destroy ( building ) ;
} else {
} else {
EventManager : : unregisterAll ( plugin_self ) ;
if ( DFHack : : Once : : doOnce ( " outsideOnly invalid setting " ) ) {
out . print ( " Error: outsideOnly: building has invalid setting: %s %d \n " , def - > code . c_str ( ) , type ) ;
}
}
}
}
}
if ( checkEvery < 0 )
return ;
EventManager : : EventHandler timeHandler ( checkBuildings , - 1 ) ;
EventManager : : registerTick ( timeHandler , checkEvery , plugin_self ) ;
}
command_result outsideOnly ( color_ostream & out , vector < string > & parameters ) {
command_result outsideOnly ( color_ostream & out , vector < string > & parameters ) {
int32_t status = 2 ;
int32_t status = 2 ;
for ( size_t a = 0 ; a < parameters . size ( ) ; a + + ) {
for ( size_t a = 0 ; a < parameters . size ( ) ; a + + ) {
@ -95,15 +146,25 @@ command_result outsideOnly(color_ostream& out, vector<string>& parameters) {
status = INSIDE_ONLY ;
status = INSIDE_ONLY ;
} else if ( parameters [ a ] = = " either " ) {
} else if ( parameters [ a ] = = " either " ) {
status = EITHER ;
status = EITHER ;
} else {
} else if ( parameters [ a ] = = " checkEvery " ) {
if ( a + 1 > = parameters . size ( ) ) {
out . printerr ( " You must specify how often to check. \n " ) ;
return CR_WRONG_USAGE ;
}
checkEvery = atoi ( parameters [ a ] . c_str ( ) ) ;
}
else {
if ( status = = 2 ) {
if ( status = = 2 ) {
out . print ( " Error: you need to tell outsideOnly whether the building is inside only, outside-only or either. \n " ) ;
out . print err ( " Error: you need to tell outsideOnly whether the building is inside only, outside-only or either. \n " ) ;
return CR_WRONG_USAGE ;
return CR_WRONG_USAGE ;
}
}
registeredBuildings [ parameters [ a ] ] = status ;
registeredBuildings [ parameters [ a ] ] = status ;
}
}
}
}
out . print ( " outsideOnly is %s \n " , enabled ? " enabled " : " disabled " ) ;
out . print ( " outsideOnly is %s \n " , enabled ? " enabled " : " disabled " ) ;
if ( enabled ) {
}
return CR_OK ;
return CR_OK ;
}
}