/* $Id: theme.cpp,v 1.17.2.1 2006/01/20 11:23:31 chfreund Exp $ */ #include "constants.hpp" #include "theme.hpp" // include source for template instanciation #include "itemset.cpp" /**********************************************************/ // setting attributes #define SATTR (Setting::COMMA_SEPARATED | \ Setting::EXPLICIT_ASSIGNMENT | \ Setting::CONFIG_FILE_ONLY) #define SATTRM (SATTR | Setting::MANDATORY) #define SETTING_STRING(ID) Theme::m_SettingDef[ID].m_IDString /**********************************************************/ const SettingDef Theme:: m_SettingDef[Theme::NUM_SETTING_DEFS+1] = { SettingDef("name", NULL, Setting::STRING, 1, 1, SATTRM), SettingDef("description", NULL, Setting::STRING, 1,-1, SATTR), SettingDef("thumbnail", NULL, Setting::STRING, 1,-1, SATTR), SettingDef("size", NULL, Setting::INT, 2, 2, SATTR), SettingDef("earth", NULL, Setting::BOOL, 1, 1, SATTR), SettingDef("waveground", NULL, Setting::BOOL, 1, 1, SATTR), SettingDef("mapstuff", NULL, Setting::STRING, 2, 2, SATTR), SettingDef("structure", NULL, Setting::STRING, 2, 2, SATTR), SettingDef("density", NULL, Setting::REAL, 1, 1, SATTR), SettingDef("sdensity", NULL, Setting::REAL, 1, 1, SATTR), SettingDef("bonusconfig", NULL, Setting::STRING, 1, 1, SATTRM), SettingDef("objectconfig", NULL, Setting::STRING, 2, 2, SATTR), SettingDef("lockedareas", NULL, Setting::STRING, 2, 2, SATTR), SettingDef("background", NULL, Setting::STRING, 1,-1, SATTR), SettingDef() }; /**********************************************************/ Theme::Theme( const char* const name, const Uint32 randomseed ) : m_Name(name), m_Description("no yet loaded"), m_ThumbNail(0x0), m_Width(-1), m_Height(-1), m_MapStuff(randomseed), m_EarthStructure(randomseed), m_Density(2.0), m_sDensity(0.6), m_fillWithEarth(true), m_useWaveGround(true), m_BonusConfig(THEME_DEFAULT_BONUS_CONFIG_PATH) { } /**********************************************************/ Theme::~Theme() { reset(); } /**********************************************************/ bool Theme::load( const char* const configpath, const char* const configfile ) { const char fn[] = "Theme::load:"; INFO( "%s loading theme \"%s\" from \"%s\"\n", fn, (char*)getName(), configfile ); // RANDOM_CIRCLES_WOP_MAP_THEME defined in constants.hpp if( m_Name == RANDOM_CIRCLES_WOP_MAP_THEME ) return true; String fullpath( configpath ); const int basepathlength = fullpath.getLength() + 1; // build full path fullpath += '/'; fullpath += configfile; // read settings SettingDataBase settings; if( !CHECK( loadSettings(fullpath, settings), "%s could not load settings for theme \"%s\" from " "\"%s\"\n", fn, (char*)getName(), configfile ) ) { return false; } ////////////////////////////////////////////// // load the map stuff ////////////////////////////////////////////// Setting* setting = settings.getSetting (SETTING_STRING(MAPSTUFF_SETTING_DEF)); if( setting != NULL ) { // build the full path fullpath.cut( basepathlength ); fullpath += setting->getString(0); if( !CHECK( m_MapStuff.load(fullpath, setting->getString(1)), "%s could not load map stuff from \"%s\"\n", fn, setting->getString(1) ) ) { return false; } } ////////////////////////////////////////////// // load structure maps ////////////////////////////////////////////// setting = settings.getSetting(SETTING_STRING(EARTH_STRUCTURE_DEF)); if( setting != NULL ) { if( CHECK( isEarthFilled(), "%s theme is not filled with earth -> " "ignoring structure maps.", fn ) ) { // build full path fullpath.cut( basepathlength ); fullpath += setting->getString(0); if( !CHECK( m_EarthStructure.load(fullpath, setting->getString(1)), "%s could not load earth structure maps " "from \"%s\"\n", fn, setting->getString(1) ) ) { return false; } // check if all structure maps have material DIGGABLE // It would not be a problem, if one of them has a material // different from DIGGABLE, since the material is ignored in // earth structures anyway, but it might lead to results, that // were not intended by the designer of the theme. for( int material = MapStuffSet::DIGGABLE+1; material < MapStuffSet::NUM_MATERIALS; material++ ) { if( !CHECK( false == m_EarthStructure.hasItemOfMaterial(material), "%s found material of an earth structure map " "being \"%s\"; must be \"DIGGABLE\"\n", fn, MapStuffSet::getMaterialString(material) ) ) { return false; } } } } ////////////////////////////////////////////// // load object sets ////////////////////////////////////////////// setting = settings.getSetting(SETTING_STRING(OBJECT_CONFIG_DEF)); if( setting != NULL ) { // build the full path fullpath.cut( basepathlength ); fullpath += setting->getString(0); // load the object list if( !CHECK( m_Objects.load( fullpath.getString(), setting->getString(1) ), "%s could not load object list\n", fn ) ) { return false; } } ////////////////////////////////////////////// // load set of locked areas ////////////////////////////////////////////// setting = settings.getSetting(SETTING_STRING(LOCKED_AREAS_DEF)); if( setting != NULL ) { // build the full path fullpath.cut( basepathlength ); fullpath += setting->getString(0); // load the object list // catch any error from loading routine if( !CHECK( m_lockedAreas.load( fullpath.getString(), setting->getString(1) ), "%s could not load locked area list\n", fn ) || // do not allow 0 loaded areas in this case !CHECK( m_lockedAreas.getNumItems(), "%s could not find locked areas in section\n" "\"%s\" of file \"%s\"\n", fn,setting->getString(1), fullpath.getString() ) ) { return false; } } return true; } /**********************************************************/ String& Theme::loadDescription( const char* const configfile ) { const char fn[] = "Theme::loadDescription:"; SettingDataBase settings; if( !CHECK( loadSettings(configfile, settings), "%s could not load settings for theme \"%s\" from " "\"%s\"\n", fn, (char*)getName(), configfile ) ) { } return m_Description; } /**********************************************************/ void Theme::reset() { m_Name.reset(); m_MapStuff.reset(); m_EarthStructure.reset(); m_Objects.reset(); m_BonusConfig.reset(); m_ObjectConfig.reset(); m_lockedAreas.reset(); delete m_ThumbNail; m_ThumbNail = 0x0; } /**********************************************************/ bool Theme::loadSettings( const char* const configfile, SettingDataBase& settings ) { const char fn[] = "Theme::loadSettings"; // read settings bool pickySuccess = true; // restrict reading settings.restrictToSection( m_Name.getString() ); // settings must have been readable if( !CHECK( settings.readSettings(m_SettingDef, configfile, true, &pickySuccess) // must have been pickily successful && pickySuccess // settings must pass the builtin check && settings.finalCheck(m_SettingDef), // output for CHECK "%s: could not read settings for theme \"%s\" from " "file \"%s\"\n", fn, (char*)m_Name, configfile ) // check the identification of the theme || !CHECK( m_Name == (String)settings .getSetting(SETTING_STRING(NAME_SETTING_DEF)) ->getString(), "%s: theme \"%s\" identified itself as \"%s\" -> go " "and check the configuration file\n", fn, m_Name.getString(), settings.getSetting(SETTING_STRING(NAME_SETTING_DEF))->getString() ) ) { return false; } Setting* setting = NULL; // get description, if available if( NULL != (setting = settings.getSetting (SETTING_STRING(DESCRIPTION_SETTING_DEF))) ) { m_Description = setting->getString(); } else { m_Description = "not available"; } // load small illustration of the theme, if available if( NULL != (setting = settings.getSetting( (SETTING_STRING(THUMBNAIL_SETTING_DEF)))) ) { m_ThumbNail = NEW Sprite(); if( !CHECK(m_ThumbNail->loadImage(setting->getString()), "%s: could not load image from \"%s\"\n") ) { delete m_ThumbNail; m_ThumbNail = 0x0; } } // get map dimension, if set if( NULL != (setting = settings.getSetting (SETTING_STRING(SIZE_SETTING_DEF))) ) { m_Width = setting->getInt( 0 ); m_Height = setting->getInt( 1 ); if( !CHECK( m_Width >= 100 && m_Height >= 100, "%s: theme defines map of size %d x %d (minimum " "100 x 100). This will probably cause consecutive " "errors.\n", fn, m_Width, m_Height ) ) { m_Width = m_Height = -1; return false; } } // get earth flag, if set if( NULL != (setting = settings.getSetting (SETTING_STRING(EARTH_SETTING_DEF))) ) { m_fillWithEarth = setting->getBool(); } // get ground flag, if set if( NULL != (setting = settings.getSetting (SETTING_STRING(WAVEGROUND_SETTING_DEF))) ) { m_useWaveGround = setting->getBool(); } // check and set the map stuff density if( NULL != (setting = settings.getSetting (SETTING_STRING(DENSITY_SETTING_DEF))) ) { if( CHECK(setting->getReal() >= 0, "%s: map stuff density < 0 -> setting to 0\n", fn) ) { m_Density = setting->getReal(); } else { m_Density = 0.0; } } // check and set the structure density if( NULL != (setting = settings.getSetting (SETTING_STRING(SDENSITY_SETTING_DEF))) ) { if( CHECK(setting->getReal() >= 0, "%s: structure density < 0 -> setting to 0\n", fn) ) { m_sDensity = setting->getReal(); } else { m_sDensity = 0.0; } } // only copy the path to the bonus configuration file if( NULL != (setting = settings.getSetting (SETTING_STRING(BONUS_CONFIG_DEF))) ) { m_BonusConfig = setting->getString(); } // only copy the path to the object configuration file if( NULL != (setting = settings.getSetting (SETTING_STRING(OBJECT_CONFIG_DEF))) ) { m_ObjectConfig = setting->getString(); } // only copy the path to the background file if( NULL != (setting = settings.getSetting (SETTING_STRING(BACKGROUND_DEF))) ) { m_Background = setting->getString(); } return true; } /**********************************************************/