2015-01-07 14:27:48 -07:00
//Blueprint
//By cdombroski
//Translates a region of tiles specified by the cursor and arguments/prompts into a series of blueprint files suitable for digfort/buildingplan/quickfort
# include <Console.h>
# include <PluginManager.h>
2015-01-12 09:52:46 -07:00
# include "modules/Buildings.h"
# include "modules/Gui.h"
# include "modules/MapCache.h"
2015-01-09 14:00:47 -07:00
# include "df/building_axle_horizontalst.h"
# include "df/building_bridgest.h"
# include "df/building_constructionst.h"
# include "df/building_furnacest.h"
# include "df/building_rollersst.h"
# include "df/building_screw_pumpst.h"
# include "df/building_siegeenginest.h"
# include "df/building_trapst.h"
# include "df/building_water_wheelst.h"
# include "df/building_workshopst.h"
2015-01-07 14:27:48 -07:00
using std : : string ;
using std : : endl ;
using std : : vector ;
using std : : ofstream ;
2015-01-09 14:00:47 -07:00
using std : : swap ;
2015-01-07 14:27:48 -07:00
using namespace DFHack ;
2015-01-09 14:00:47 -07:00
using namespace df : : enums ;
2015-01-07 14:27:48 -07:00
DFHACK_PLUGIN ( " blueprint " ) ;
enum phase { DIG , BUILD , PLACE , QUERY } ;
command_result blueprint ( color_ostream & out , vector < string > & parameters ) ;
DFhackCExport command_result plugin_init ( color_ostream & out , vector < PluginCommand > & commands )
{
commands . push_back ( PluginCommand ( " blueprint " , " Convert map tiles into a blueprint " , blueprint , false ) ) ;
return CR_OK ;
}
DFhackCExport command_result plugin_shutdown ( color_ostream & out )
{
return CR_OK ;
}
command_result help ( color_ostream & out )
{
out < < " blueprint width height depth name [dig [build [place [query]]]] " < < endl
< < " width, height, depth: area to translate in tiles " < < endl
< < " name: base name for blueprint files " < < endl
< < " dig: generate blueprints for digging " < < endl
< < " build: generate blueprints for building " < < endl
< < " place: generate blueprints for stockpiles " < < endl
< < " query: generate blueprints for querying (room designations) " < < endl
< < " defaults to generating all blueprints " < < endl
< < endl
< < " blueprint translates a portion of your fortress into blueprints suitable for " < < endl
< < " digfort/fortplan/quickfort. Blueprints are created in the DF folder with names " < < endl
< < " following a \" name-phase.csv \" pattern. Translation starts at the current " < < endl
< < " cursor location and includes all tiles in the range specified. " < < endl ;
return CR_OK ;
}
2015-01-08 10:17:18 -07:00
char get_tile_dig ( MapExtras : : MapCache mc , int32_t x , int32_t y , int32_t z )
{
2015-01-09 14:00:47 -07:00
df : : tiletype tt = mc . tiletypeAt ( DFCoord ( x , y , z ) ) ;
df : : tiletype_shape ts = tileShape ( tt ) ;
2015-01-08 10:17:18 -07:00
switch ( ts )
{
2015-01-09 14:00:47 -07:00
case tiletype_shape : : EMPTY :
case tiletype_shape : : RAMP_TOP :
2015-01-08 10:17:18 -07:00
return ' h ' ;
2015-01-09 14:00:47 -07:00
case tiletype_shape : : FLOOR :
case tiletype_shape : : BOULDER :
case tiletype_shape : : PEBBLES :
case tiletype_shape : : BROOK_TOP :
2015-01-08 10:17:18 -07:00
return ' d ' ;
2015-01-09 14:00:47 -07:00
case tiletype_shape : : FORTIFICATION :
return ' F ' ;
case tiletype_shape : : STAIR_UP :
2015-01-08 10:17:18 -07:00
return ' u ' ;
2015-01-09 14:00:47 -07:00
case tiletype_shape : : STAIR_DOWN :
2015-01-08 10:17:18 -07:00
return ' j ' ;
2015-01-09 14:00:47 -07:00
case tiletype_shape : : STAIR_UPDOWN :
2015-01-08 10:17:18 -07:00
return ' i ' ;
2015-01-09 14:00:47 -07:00
case tiletype_shape : : RAMP :
2015-01-08 10:17:18 -07:00
return ' r ' ;
default :
return ' ' ;
2015-01-09 14:00:47 -07:00
2015-01-08 10:17:18 -07:00
}
}
2015-01-07 14:27:48 -07:00
2015-01-09 14:00:47 -07:00
string get_tile_build ( df : : building * b )
{
2015-01-12 09:52:46 -07:00
if ( ! b )
return " " ;
string ret ;
2015-01-09 14:00:47 -07:00
switch ( b - > getType ( ) )
{
case building_type : : Armorstand :
return " a " ;
case building_type : : Bed :
return " b " ;
case building_type : : Chair :
return " c " ;
case building_type : : Door :
return " d " ;
case building_type : : Floodgate :
return " x " ;
case building_type : : Cabinet :
return " f " ;
case building_type : : Box :
return " h " ;
//case building_type::Kennel is missing
case building_type : : FarmPlot :
return " p " ;
case building_type : : Weaponrack :
return " r " ;
case building_type : : Statue :
return " s " ;
case building_type : : Table :
return " t " ;
case building_type : : RoadPaved :
return " o " ;
case building_type : : RoadDirt :
return " O " ;
case building_type : : Bridge :
switch ( ( ( df : : building_bridgest * ) b ) - > direction )
{
case df : : building_bridgest : : T_direction : : Down :
return " gx " ;
case df : : building_bridgest : : T_direction : : Left :
return " ga " ;
case df : : building_bridgest : : T_direction : : Up :
return " gw " ;
case df : : building_bridgest : : T_direction : : Right :
return " gd " ;
case df : : building_bridgest : : T_direction : : Retracting :
return " gs " ;
}
case building_type : : Well :
return " l " ;
case building_type : : SiegeEngine :
2015-01-12 09:52:46 -07:00
return ( ( df : : building_siegeenginest * ) b ) - > type = = df : : siegeengine_type : : Ballista ? " ib " : " ic " ;
2015-01-09 14:00:47 -07:00
case building_type : : Workshop :
switch ( ( ( df : : building_workshopst * ) b ) - > type )
{
case workshop_type : : Leatherworks :
return " we " ;
case workshop_type : : Quern :
return " wq " ;
case workshop_type : : Millstone :
return " wM " ;
case workshop_type : : Loom :
return " wo " ;
case workshop_type : : Clothiers :
return " wk " ;
case workshop_type : : Bowyers :
return " wb " ;
case workshop_type : : Carpenters :
return " wc " ;
case workshop_type : : MetalsmithsForge :
return " wf " ;
case workshop_type : : MagmaForge :
return " wv " ;
case workshop_type : : Jewelers :
return " wj " ;
case workshop_type : : Masons :
return " wm " ;
case workshop_type : : Butchers :
return " wu " ;
case workshop_type : : Tanners :
return " wn " ;
case workshop_type : : Craftsdwarfs :
return " wr " ;
case workshop_type : : Siege :
return " ws " ;
case workshop_type : : Mechanics :
return " wt " ;
case workshop_type : : Still :
return " wl " ;
case workshop_type : : Farmers :
return " ww " ;
case workshop_type : : Kitchen :
return " wz " ;
case workshop_type : : Fishery :
return " wh " ;
case workshop_type : : Ashery :
return " wy " ;
case workshop_type : : Dyers :
return " wd " ;
case workshop_type : : Custom :
//can't do anything with custom workshop
return " " ;
}
case building_type : : Furnace :
switch ( ( ( df : : building_furnacest * ) b ) - > type )
{
case furnace_type : : WoodFurnace :
return " ew " ;
case furnace_type : : Smelter :
return " es " ;
case furnace_type : : GlassFurnace :
return " eg " ;
case furnace_type : : Kiln :
return " ek " ;
case furnace_type : : MagmaSmelter :
return " el " ;
case furnace_type : : MagmaGlassFurnace :
return " ea " ;
case furnace_type : : MagmaKiln :
return " en " ;
case furnace_type : : Custom :
//can't do anything with custom furnace
return " " ;
}
case building_type : : WindowGlass :
return " y " ;
case building_type : : WindowGem :
return " Y " ;
case building_type : : Construction :
switch ( ( ( df : : building_constructionst * ) b ) - > type )
{
case construction_type : : Fortification :
return " CF " ;
case construction_type : : Wall :
return " CW " ;
case construction_type : : Floor :
return " Cf " ;
case construction_type : : UpStair :
return " Cu " ;
case construction_type : : DownStair :
return " Cj " ;
case construction_type : : UpDownStair :
return " Cx " ;
case construction_type : : Ramp :
return " Cr " ;
case construction_type : : TrackN :
return " trackN " ;
case construction_type : : TrackS :
return " trackS " ;
case construction_type : : TrackE :
return " trackE " ;
case construction_type : : TrackW :
return " trackW " ;
case construction_type : : TrackNS :
return " trackNS " ;
case construction_type : : TrackNE :
return " trackNE " ;
case construction_type : : TrackNW :
return " trackNW " ;
case construction_type : : TrackSE :
return " trackSE " ;
case construction_type : : TrackSW :
return " trackSW " ;
case construction_type : : TrackEW :
return " trackEW " ;
case construction_type : : TrackNSE :
return " trackNSE " ;
case construction_type : : TrackNSW :
return " trackNSW " ;
case construction_type : : TrackNEW :
return " trackNEW " ;
case construction_type : : TrackSEW :
return " trackSEW " ;
case construction_type : : TrackNSEW :
return " trackNSEW " ;
case construction_type : : TrackRampN :
return " trackrampN " ;
case construction_type : : TrackRampS :
return " trackrampS " ;
case construction_type : : TrackRampE :
return " trackrampE " ;
case construction_type : : TrackRampW :
return " trackrampW " ;
case construction_type : : TrackRampNS :
return " trackrampNS " ;
case construction_type : : TrackRampNE :
return " trackrampNE " ;
case construction_type : : TrackRampNW :
return " trackrampNW " ;
case construction_type : : TrackRampSE :
return " trackrampSE " ;
case construction_type : : TrackRampSW :
return " trackrampSW " ;
case construction_type : : TrackRampEW :
return " trackrampEW " ;
case construction_type : : TrackRampNSE :
return " trackrampNSE " ;
case construction_type : : TrackRampNSW :
return " trackrampNSW " ;
case construction_type : : TrackRampNEW :
return " trackrampNEW " ;
case construction_type : : TrackRampSEW :
return " trackrampSEW " ;
case construction_type : : TrackRampNSEW :
return " trackrampNSEW " ;
}
case building_type : : Shop :
return " z " ;
case building_type : : AnimalTrap :
return " m " ;
case building_type : : Chain :
return " v " ;
case building_type : : Cage :
return " j " ;
case building_type : : TradeDepot :
return " D " ;
case building_type : : Trap :
switch ( ( ( df : : building_trapst * ) b ) - > trap_type )
{
case trap_type : : StoneFallTrap :
return " Ts " ;
case trap_type : : WeaponTrap :
return " Tw " ;
case trap_type : : Lever :
return " Tl " ;
case trap_type : : PressurePlate :
return " Tp " ;
case trap_type : : CageTrap :
return " Tc " ;
case trap_type : : TrackStop :
df : : building_trapst * ts = ( df : : building_trapst * ) b ;
2015-01-12 09:52:46 -07:00
ret = " CS " ;
2015-01-09 14:00:47 -07:00
if ( ts - > use_dump )
{
if ( ts - > dump_x_shift = = 0 )
{
if ( ts - > dump_y_shift > 0 )
ret + = " dd " ;
else
ret + = " d " ;
}
else
{
if ( ts - > dump_x_shift > 0 )
ret + = " ddd " ;
else
ret + = " dddd " ;
}
}
switch ( ts - > friction )
{
case 10 :
ret + = " a " ;
case 50 :
ret + = " a " ;
case 500 :
ret + = " a " ;
case 10000 :
ret + = " a " ;
}
return ret ;
}
case building_type : : ScrewPump :
switch ( ( ( df : : building_screw_pumpst * ) b ) - > direction )
{
case screw_pump_direction : : FromNorth :
return " Msu " ;
case screw_pump_direction : : FromEast :
return " Msk " ;
case screw_pump_direction : : FromSouth :
return " Msm " ;
case screw_pump_direction : : FromWest :
return " Msh " ;
}
case building_type : : WaterWheel :
//s swaps orientation which defaults to vertical
return " Mw " + ( ( df : : building_water_wheelst * ) b ) - > is_vertical ? " " : " s " ;
case building_type : : Windmill :
return " Mm " ;
case building_type : : GearAssembly :
return " Mg " ;
case building_type : : AxleHorizontal :
//same as water wheel but reversed
return " Mh " + ( ( df : : building_axle_horizontalst * ) b ) - > is_vertical ? " s " : " " ;
case building_type : : AxleVertical :
return " Mv " ;
case building_type : : Rollers :
2015-01-12 09:52:46 -07:00
ret = " Mr " ;
2015-01-09 14:00:47 -07:00
switch ( ( ( df : : building_rollersst * ) b ) - > direction )
{
case screw_pump_direction : : FromNorth :
break ;
case screw_pump_direction : : FromEast :
ret + = " s " ;
case screw_pump_direction : : FromSouth :
ret + = " s " ;
case screw_pump_direction : : FromWest :
ret + = " s " ;
}
return ret ;
case building_type : : Support :
return " S " ;
case building_type : : ArcheryTarget :
return " A " ;
case building_type : : TractionBench :
return " R " ;
case building_type : : Hatch :
return " H " ;
case building_type : : Slab :
//how to mine alt key?!?
//alt+s
return " " ;
case building_type : : NestBox :
return " N " ;
case building_type : : Hive :
//alt+h
return " " ;
case building_type : : GrateWall :
return " W " ;
case building_type : : GrateFloor :
return " G " ;
case building_type : : BarsVertical :
return " B " ;
case building_type : : BarsFloor :
//alt+b
return " " ;
default :
return " " ;
}
}
2015-01-08 10:17:18 -07:00
command_result do_transform ( DFCoord start , DFCoord end , string name , phase last_phase )
2015-01-07 14:27:48 -07:00
{
ofstream dig , build , place , query ;
switch ( last_phase )
{
case QUERY :
query = ofstream ( name + " -query.csv " , ofstream : : trunc ) ;
query < < " #query " < < endl ;
case PLACE :
place = ofstream ( name + " -place.csv " , ofstream : : trunc ) ;
place < < " #place " < < endl ;
case BUILD :
build = ofstream ( name + " -build.csv " , ofstream : : trunc ) ;
build < < " #build " < < endl ;
case DIG :
dig = ofstream ( name + " -dig.csv " , ofstream : : trunc ) ;
dig < < " #dig " < < endl ;
}
if ( start . x > end . x )
{
swap ( start . x , end . x ) ;
2015-01-08 10:17:18 -07:00
start . x + + ;
end . x + + ;
2015-01-07 14:27:48 -07:00
}
if ( start . y > end . y )
{
swap ( start . y , end . y ) ;
2015-01-08 10:17:18 -07:00
start . y + + ;
end . y + + ;
2015-01-07 14:27:48 -07:00
}
if ( start . z > end . z )
{
swap ( start . z , end . z ) ;
2015-01-08 10:17:18 -07:00
start . z + + ;
end . z + + ;
2015-01-07 14:27:48 -07:00
}
MapExtras : : MapCache mc ;
2015-01-08 10:17:18 -07:00
for ( int32_t z = start . z ; z < end . z ; z + + )
2015-01-07 14:27:48 -07:00
{
2015-01-08 10:17:18 -07:00
for ( int32_t y = start . y ; y < end . y ; y + + )
2015-01-07 14:27:48 -07:00
{
2015-01-08 10:17:18 -07:00
for ( int32_t x = start . x ; x < end . x ; x + + )
2015-01-07 14:27:48 -07:00
{
2015-01-09 14:00:47 -07:00
df : : building * b = DFHack : : Buildings : : findAtTile ( DFCoord ( x , y , z ) ) ;
2015-01-07 14:27:48 -07:00
switch ( last_phase ) {
case QUERY :
case PLACE :
case BUILD :
2015-01-09 14:00:47 -07:00
build < < get_tile_build ( b ) < < ' , ' ;
2015-01-07 14:27:48 -07:00
case DIG :
2015-01-08 10:17:18 -07:00
dig < < get_tile_dig ( mc , x , y , z ) < < ' , ' ;
2015-01-07 14:27:48 -07:00
}
}
switch ( last_phase ) {
case QUERY :
query < < " # " < < endl ;
case PLACE :
place < < " # " < < endl ;
case BUILD :
2015-01-08 10:17:18 -07:00
build < < " # " < < endl ;
2015-01-07 14:27:48 -07:00
case DIG :
dig < < " # " < < endl ;
}
}
if ( z < end . z - 1 )
switch ( last_phase ) {
case QUERY :
2015-01-08 10:17:18 -07:00
query < < " #< " < < endl ;
2015-01-07 14:27:48 -07:00
case PLACE :
2015-01-08 10:17:18 -07:00
place < < " #< " < < endl ;
2015-01-07 14:27:48 -07:00
case BUILD :
2015-01-08 10:17:18 -07:00
build < < " #< " < < endl ;
2015-01-07 14:27:48 -07:00
case DIG :
2015-01-08 10:17:18 -07:00
dig < < " #< " < < endl ;
2015-01-09 14:00:47 -07:00
}
2015-01-07 14:27:48 -07:00
}
switch ( last_phase ) {
case QUERY :
query . close ( ) ;
case PLACE :
place . close ( ) ;
case BUILD :
2015-01-08 10:17:18 -07:00
build . close ( ) ;
2015-01-07 14:27:48 -07:00
case DIG :
dig . close ( ) ;
}
return CR_OK ;
}
command_result blueprint ( color_ostream & out , vector < string > & parameters )
{
if ( parameters . size ( ) < 4 | | parameters . size ( ) > 8 )
return help ( out ) ;
CoreSuspender suspend ;
if ( ! Maps : : IsValid ( ) )
{
out . printerr ( " Map is not available! \n " ) ;
return CR_FAILURE ;
}
int32_t x , y , z ;
if ( ! Gui : : getCursorCoords ( x , y , z ) )
{
out . printerr ( " Can't get cursor coords! Make sure you have an active cursor in DF. \n " ) ;
return CR_FAILURE ;
}
DFCoord start ( x , y , z ) ;
2015-01-08 10:17:18 -07:00
DFCoord end ( x + stoi ( parameters [ 0 ] ) , y + stoi ( parameters [ 1 ] ) , z + stoi ( parameters [ 2 ] ) ) ;
2015-01-07 14:27:48 -07:00
switch ( parameters . size ( ) )
{
case 4 :
case 8 :
2015-01-08 10:17:18 -07:00
return do_transform ( start , end , parameters [ 3 ] , QUERY ) ;
2015-01-07 14:27:48 -07:00
case 5 :
2015-01-08 10:17:18 -07:00
return do_transform ( start , end , parameters [ 3 ] , DIG ) ;
2015-01-07 14:27:48 -07:00
case 6 :
2015-01-08 10:17:18 -07:00
return do_transform ( start , end , parameters [ 3 ] , BUILD ) ;
2015-01-07 14:27:48 -07:00
case 7 :
2015-01-08 10:17:18 -07:00
return do_transform ( start , end , parameters [ 3 ] , PLACE ) ;
2015-01-07 14:27:48 -07:00
default : //wtf?
return CR_FAILURE ;
}
}