2017-01-25 10:36:03 -07:00
# include "Console.h"
# include "Core.h"
# include "DataDefs.h"
# include "Export.h"
# include "PluginManager.h"
# include "df/world.h"
# include "df/world_raws.h"
# include "df/creature_raw.h"
# include "df/caste_raw.h"
2017-01-26 00:15:40 -07:00
# include "modules/World.h"
2017-02-07 03:27:35 -07:00
# include "MemAccess.h"
2017-01-25 10:36:03 -07:00
//#include "df/world.h"
using namespace DFHack ;
2017-01-25 21:30:38 -07:00
DFHACK_PLUGIN ( " generated-creature-renamer " ) ;
2017-01-25 10:36:03 -07:00
REQUIRE_GLOBAL ( world ) ;
2017-02-06 22:39:39 -07:00
# define RENAMER_VERSION 3
2017-02-05 22:12:10 -07:00
2017-01-26 00:15:40 -07:00
command_result list_creatures ( color_ostream & out , std : : vector < std : : string > & parameters ) ;
2017-02-06 22:49:45 -07:00
command_result save_generated_raw ( color_ostream & out , std : : vector < std : : string > & parameters ) ;
2017-01-25 10:36:03 -07:00
2017-01-26 00:15:40 -07:00
DFhackCExport command_result plugin_init ( color_ostream & out , std : : vector < PluginCommand > & commands )
2017-01-25 10:36:03 -07:00
{
2017-01-26 00:15:40 -07:00
commands . push_back ( PluginCommand (
" list-generated " ,
2017-02-07 03:27:35 -07:00
" Prints a list of generated creature tokens. " ,
2017-01-26 00:15:40 -07:00
list_creatures ,
false , //allow non-interactive use
2017-02-07 03:27:35 -07:00
" Use \" list-generated detailed \" to show descriptions. "
2017-01-25 10:36:03 -07:00
) ) ;
2017-02-06 22:49:45 -07:00
commands . push_back ( PluginCommand (
" save-generated-raws " ,
" Saves a graphics raw file to use with the renamed generated creatures. " ,
save_generated_raw ,
false , //allow non-interactive use
2017-02-07 03:27:35 -07:00
" Creates graphics_procedural_creatures.txt, with a full set of creature graphics definitions for all possible generated beasts. Modify the resulting file to suit your needs. "
2017-02-06 22:49:45 -07:00
) ) ; return CR_OK ;
2017-01-25 10:36:03 -07:00
}
2017-01-26 00:15:40 -07:00
DFhackCExport command_result plugin_shutdown ( color_ostream & out )
2017-01-25 10:36:03 -07:00
{
return CR_OK ;
}
2017-01-26 03:28:43 -07:00
DFHACK_PLUGIN_IS_ENABLED ( is_enabled ) ;
2017-01-26 00:15:40 -07:00
2017-01-26 03:28:43 -07:00
DFhackCExport command_result plugin_enable ( color_ostream & out , bool enable )
{
is_enabled = enable ;
return CR_OK ;
}
2017-01-26 00:15:40 -07:00
2017-02-06 21:57:57 -07:00
std : : vector < std : : string > descriptors = {
" blob " , " quadruped " , " humanoid " , " silverfish " , " mayfly " , " dragonfly " , " damselfly " , " stonefly " ,
" earwig " , " grasshopper " , " cricket " , " stick insect " , " cockroach " , " termite " , " mantis " , " louse " ,
" thrips " , " aphid " , " cicada " , " assassin bug " , " wasp " , " hornet " , " tiger beetle " , " ladybug " ,
2017-02-07 22:24:42 -07:00
" weevil " , " darkling beetle " , " click beetle " , " firefly " , " scarab beetle " , " stag beetle " , " dung beetle " , " rhinoceros beetle " ,
" rove beetle " , " snakefly " , " lacewing " , " antlion larva " , " mosquito " , " flea " , " scorpionfly " , " caddisfly " ,
2017-02-06 21:57:57 -07:00
" butterfly " , " moth " , " caterpillar " , " maggot " , " spider " , " tarantula " , " scorpion " , " tick " ,
" mite " , " shrimp " , " lobster " , " crab " , " nematode " , " snail " , " slug " , " earthworm " ,
" leech " , " bristleworm " , " ribbon worm " , " flat worm " , " toad " , " frog " , " salamander " , " newt " ,
2017-02-07 22:24:42 -07:00
" alligator " , " crocodile " , " lizard " , " chameleon " , " iguana " , " gecko " , " skink " , " gila monster " ,
2017-02-06 21:57:57 -07:00
" monitor " , " serpent " , " viper " , " rattlesnake " , " cobra " , " python " , " anaconda " , " turtle " ,
" tortoise " , " pterosaur " , " dimetrodon " , " sauropod " , " theropod " , " iguanodont " , " hadrosaurid " , " stegosaurid " ,
2017-02-07 22:24:42 -07:00
" ceratopsid " , " ankylosaurid " , " duck " , " goose " , " swan " , " turkey " , " grouse " , " chicken " ,
2017-02-06 21:57:57 -07:00
" quail " , " pheasant " , " gull " , " loon " , " grebe " , " albatross " , " petrel " , " penguin " ,
" pelican " , " stork " , " vulture " , " flamingo " , " falcon " , " kestrel " , " condor " , " osprey " ,
" buzzard " , " eagle " , " harrier " , " kite " , " crane " , " dove " , " pigeon " , " parrot " ,
" cockatoo " , " cuckoo " , " nightjar " , " swift " , " hummingbird " , " kingfisher " , " hornbill " , " quetzal " ,
2017-02-07 22:24:42 -07:00
" toucan " , " woodpecker " , " lyrebird " , " thornbill " , " honeyeater " , " oriole " , " fantail " , " shrike " ,
2017-02-06 21:57:57 -07:00
" crow " , " raven " , " magpie " , " kinglet " , " lark " , " swallow " , " martin " , " bushtit " ,
" warbler " , " thrush " , " oxpecker " , " starling " , " mockingbird " , " wren " , " nuthatch " , " sparrow " ,
" tanager " , " cardinal " , " bunting " , " finch " , " titmouse " , " chickadee " , " waxwing " , " flycatcher " ,
" opossum " , " koala " , " wombat " , " kangaroo " , " sloth " , " anteater " , " armadillo " , " squirrel " ,
2017-02-07 22:24:42 -07:00
" marmot " , " beaver " , " gopher " , " mouse " , " porcupine " , " chinchilla " , " cavy " , " capybara " ,
" rabbit " , " hare " , " lemur " , " loris " , " monkey " , " hedgehog " , " shrew " , " mole " ,
2017-02-06 21:57:57 -07:00
" fruit bat " , " wolf " , " coyote " , " jackal " , " raccoon " , " coati " , " weasel " , " otter " ,
" badger " , " skunk " , " bear " , " panda " , " panther " , " mongoose " , " hyena " , " civet " ,
" walrus " , " pangolin " , " elephant " , " mammoth " , " horse " , " zebra " , " tapir " , " rhinoceros " ,
2017-02-07 22:24:42 -07:00
" warthog " , " hippopotamus " , " camel " , " llama " , " giraffe " , " deer " , " moose " , " antelope " ,
2017-02-06 21:57:57 -07:00
" sheep " , " goat " , " bison " , " buffalo " , " bull " , " ape " , " ant " , " bat " ,
2017-02-07 22:24:42 -07:00
" owl " , " pig " , " bee " , " fly " , " hawk " , " jay " , " rat " , " fox " ,
2017-02-06 21:57:57 -07:00
" cat " , " ass " , " elk "
} ;
2017-01-26 03:28:43 -07:00
2017-02-06 22:31:42 -07:00
std : : vector < std : : string > prefixes = {
" FORGOTTEN_BEAST_ " ,
" TITAN_ " ,
" DEMON_ " ,
" NIGHT_CREATURE_ " ,
" HF "
} ;
2017-01-26 03:28:43 -07:00
DFhackCExport command_result plugin_onstatechange ( color_ostream & out , state_change_event event )
{
if ( ! is_enabled )
2017-01-26 00:15:40 -07:00
return CR_OK ;
2017-02-07 03:27:35 -07:00
if ( event ! = DFHack : : SC_WORLD_LOADED )
return CR_OK ;
CoreSuspender suspend ;
std : : vector < int > descriptorCount = std : : vector < int > ( descriptors . size ( ) ) ;
auto version = World : : GetPersistentData ( " AlreadyRenamedCreatures " ) ;
if ( version . isValid ( ) & & version . ival ( 1 ) > = RENAMER_VERSION )
2017-01-26 00:15:40 -07:00
{
2017-02-07 03:27:35 -07:00
return CR_OK ;
}
2017-01-26 00:15:40 -07:00
2017-02-07 03:27:35 -07:00
int creatureCount = 0 ;
2017-01-26 03:28:43 -07:00
2018-04-06 00:18:15 -06:00
for ( size_t i = 0 ; i < world - > raws . creatures . all . size ( ) ; i + + )
2017-02-07 03:27:35 -07:00
{
auto creatureRaw = world - > raws . creatures . all [ i ] ;
if ( ! creatureRaw - > flags . is_set ( df : : enums : : creature_raw_flags : : GENERATED ) )
continue ;
size_t minPos = std : : string : : npos ;
size_t foundIndex = - 1 ;
size_t prefixIndex = - 1 ;
2017-01-26 00:15:40 -07:00
2017-02-07 22:04:11 -07:00
for ( size_t j = 0 ; j < prefixes . size ( ) ; j + + )
2017-01-26 00:15:40 -07:00
{
2017-02-07 03:27:35 -07:00
if ( creatureRaw - > creature_id . compare ( 0 , prefixes [ j ] . length ( ) , prefixes [ j ] ) = = 0 )
2017-02-06 22:31:42 -07:00
{
2017-02-07 03:27:35 -07:00
prefixIndex = j ;
2017-02-06 22:31:42 -07:00
}
2017-02-07 03:27:35 -07:00
}
2017-02-06 22:31:42 -07:00
2017-02-07 03:27:35 -07:00
if ( prefixIndex < 0 )
continue ; //unrecognized generaed type.
2017-01-26 00:15:40 -07:00
2017-02-07 03:27:35 -07:00
for ( size_t j = 0 ; j < descriptors . size ( ) ; j + + )
{
size_t pos = creatureRaw - > caste [ 0 ] - > description . find ( " " + descriptors [ j ] ) ;
if ( pos < minPos )
2017-01-26 00:15:40 -07:00
{
2017-02-07 03:27:35 -07:00
minPos = pos ;
foundIndex = j ;
2017-01-26 00:15:40 -07:00
}
2017-02-07 03:27:35 -07:00
}
2017-01-26 00:15:40 -07:00
2017-02-07 03:27:35 -07:00
if ( foundIndex < 0 )
continue ; //can't find a match.
2017-01-26 03:28:43 -07:00
2017-02-07 03:27:35 -07:00
auto descriptor = descriptors [ foundIndex ] ;
2017-01-26 03:28:43 -07:00
2018-04-06 00:18:15 -06:00
for ( size_t j = 0 ; j < descriptor . size ( ) ; j + + )
2017-02-07 03:27:35 -07:00
{
if ( descriptor [ j ] = = ' ' )
descriptor [ j ] = ' _ ' ;
else
descriptor [ j ] = toupper ( descriptor [ j ] ) ;
}
2017-02-06 22:31:42 -07:00
2017-02-07 03:27:35 -07:00
auto prefix = prefixes [ prefixIndex ] ;
if ( prefix [ prefix . length ( ) - 1 ] ! = ' _ ' )
prefix . append ( " _ " ) ;
2017-02-06 22:39:39 -07:00
2017-02-07 03:27:35 -07:00
creatureRaw - > creature_id = prefixes [ prefixIndex ] + descriptor ;
2017-01-26 03:28:43 -07:00
2017-02-07 03:27:35 -07:00
if ( descriptorCount [ foundIndex ] > 0 )
{
creatureRaw - > creature_id . append ( " _ " + std : : to_string ( descriptorCount [ foundIndex ] ) ) ;
2017-01-26 00:15:40 -07:00
}
2017-02-07 03:27:35 -07:00
descriptorCount [ foundIndex ] + + ;
creatureCount + + ;
2017-01-26 00:15:40 -07:00
}
2017-02-07 03:27:35 -07:00
version = World : : AddPersistentData ( " AlreadyRenamedCreatures " ) ;
version . ival ( 1 ) = RENAMER_VERSION ;
out < < " Renamed " < < creatureCount < < " generated creatures to have sensible names. " < < endl ;
2017-01-26 00:15:40 -07:00
return CR_OK ;
}
command_result list_creatures ( color_ostream & out , std : : vector < std : : string > & parameters )
{
bool detailed = false ;
if ( ! parameters . empty ( ) )
{
if ( parameters . size ( ) > 1 )
return CR_WRONG_USAGE ;
if ( parameters [ 0 ] . compare ( " detailed " ) ! = 0 )
return CR_WRONG_USAGE ;
detailed = true ;
}
CoreSuspender suspend ;
2018-04-06 00:18:15 -06:00
for ( size_t i = 0 ; i < world - > raws . creatures . all . size ( ) ; i + + )
2017-01-25 10:36:03 -07:00
{
auto creatureRaw = world - > raws . creatures . all [ i ] ;
if ( ! creatureRaw - > flags . is_set ( df : : enums : : creature_raw_flags : : GENERATED ) )
continue ;
2018-06-11 10:57:06 -06:00
out . print ( " %s " , creatureRaw - > creature_id . c_str ( ) ) ;
2017-01-26 00:15:40 -07:00
if ( detailed )
{
2018-06-11 10:57:06 -06:00
out . print ( " \t %s " , creatureRaw - > caste [ 0 ] - > description . c_str ( ) ) ;
2017-01-26 00:15:40 -07:00
}
2017-01-25 21:30:38 -07:00
out . print ( " \n " ) ;
2017-01-25 10:36:03 -07:00
}
2017-02-07 03:27:35 -07:00
return CR_OK ;
2017-01-25 10:36:03 -07:00
}
2017-02-06 22:49:45 -07:00
command_result save_generated_raw ( color_ostream & out , std : : vector < std : : string > & parameters )
{
2017-02-07 03:27:35 -07:00
# ifdef LINUX_BUILD
std : : string pathSep = " / " ;
# else
std : : string pathSep = " \\ " ;
# endif
int pageWidth = 16 ;
int pageHeight = ( descriptors . size ( ) / pageWidth ) + ( ( descriptors . size ( ) % pageWidth > 0 ) ? 1 : 0 ) ;
int tileWidth = 24 ;
int tileHeight = 24 ;
std : : string fileName = " graphics_procedural_creatures " ;
std : : string pageName = " PROCEDURAL_FRIENDLY " ;
2018-04-06 00:18:15 -06:00
size_t repeats = 128 ;
2017-02-07 03:27:35 -07:00
std : : ofstream outputFile ( fileName + " .txt " , std : : ios : : out | std : : ios : : trunc ) ;
outputFile < < fileName < < endl < < endl ;
outputFile < < " [OBJECT:GRAPHICS] " < < endl < < endl ;
outputFile < < " [TILE_PAGE: " < < pageName < < " ] " < < endl ;
outputFile < < " [FILE:procedural_friendly.png] " < < endl ;
outputFile < < " [TILE_DIM: " < < tileWidth < < " : " < < tileHeight < < " ] " < < endl ;
outputFile < < " [PAGE_DIM: " < < pageWidth < < " : " < < pageHeight < < " ] " < < endl < < endl ;
for ( size_t descIndex = 0 ; descIndex < descriptors . size ( ) ; descIndex + + )
{
for ( size_t prefIndex = 0 ; prefIndex < prefixes . size ( ) ; prefIndex + + )
{
for ( size_t rep = 0 ; rep < repeats ; rep + + )
{
auto descriptor = descriptors [ descIndex ] ;
2018-04-06 00:18:15 -06:00
for ( size_t j = 0 ; j < descriptor . size ( ) ; j + + )
2017-02-07 03:27:35 -07:00
{
if ( descriptor [ j ] = = ' ' )
descriptor [ j ] = ' _ ' ;
else
descriptor [ j ] = toupper ( descriptor [ j ] ) ;
}
auto prefix = prefixes [ prefIndex ] ;
if ( prefix [ prefix . length ( ) - 1 ] ! = ' _ ' )
prefix . append ( " _ " ) ;
std : : string token = prefix + descriptor ;
if ( rep > 0 )
token . append ( " _ " + std : : to_string ( rep ) ) ;
outputFile < < " [CREATURE_GRAPHICS: " < < token < < " ] " < < endl ;
outputFile < < " [DEFAULT: " < < pageName < < " : " < < descIndex % pageWidth < < " : " < < descIndex / pageWidth < < " :ADD_COLOR] " < < endl ;
}
outputFile < < endl ;
}
outputFile < < endl ;
}
outputFile . close ( ) ;
2017-02-06 22:49:45 -07:00
return CR_OK ;
}