bool addSingleCustomBuildingConfig( TiXmlElement* elemRoot, vector<BuildingConfiguration>* knownBuildings ){ const char* strName = elemRoot->Attribute("name"); const char* strGameID = elemRoot->Attribute("gameID"); if (strName == NULL || strGameID == NULL || strName[0] == 0 || strGameID[0] == 0) { contentError("<building> node must have name and gameID attributes",elemRoot); return false; } int gameID = TranslateBuildingName(strGameID, contentLoader.custom_workshop_types ); if (gameID == INVALID_INDEX) { return false; } BuildingConfiguration building(strName, gameID ); RootBlock* spriteroot = new RootBlock(); building.sprites = spriteroot; if (!parseSpriteNode(spriteroot,elemRoot)) { delete(spriteroot); return false; } //add a copy of 'building' to known buildings knownBuildings->push_back( building ); return true; }
bool parseSpriteNode(SpriteNode* node, TiXmlElement* elemParent) { //TODO: there is a leak here somewhere. SpriteBlock* oldSibling = NULL; TiXmlElement* elemNode = elemParent->FirstChildElement(); const char* strParent = elemParent->Value(); if (elemNode == NULL) { contentError("Empty SpriteNode Element",elemParent); return false; } if ( strcmp(strParent,"building") != 0 && strcmp(strParent,"custom_workshop") != 0 && strcmp(strParent,"rotate") != 0) { //flag to allow else statements to be empty, rather than needing an "always" tag bool allowBlank = (strcmp(strParent,"else") == 0 || elemParent->Attribute("else")); // cast should be safe, because only spriteblocks // should get here int retvalue =parseConditionNode((SpriteBlock *)node,elemNode,allowBlank); if (retvalue == 0) return false; if (retvalue > 0) elemNode = elemNode->NextSiblingElement(); } while (elemNode) { if (!readNode(node, elemNode, elemParent, oldSibling)) return false; elemNode = elemNode->NextSiblingElement(); } return true; }
void CPage::loadContentError(ConnectionPtr connection) { Trace("loadContentError()", "", 0); std::string strQuery; try { Mutex::Lock lock(m_contentErrorListLock); // get all of the pages for this customer to test strQuery = Format(SQL_WTT_CONTENT_ERRORS); if (ResultPtr result = connection->Query(strQuery)) { while (result->Next()) { RowPtr row = result->GetCurrentRow(); StringIDList::value_type contentError(row->GetFieldString(1), row->GetFieldLong(2)); contentError.first = " " + contentError.first + " "; Trace("loadContentError() - loading string", contentError.first.c_str(), contentError.second); m_contentError.push_back(contentError); } } } catch (const std::exception& e) { LogError("Exception Caught:", e.what(), 0); } }
bool includeFile(SpriteNode* node, TiXmlElement* includeNode, SpriteBlock* &oldSibling) { // get path... ugly char configfilepath[FILENAME_BUFFERSIZE] = {0}; const char* documentRef = getDocument(includeNode); if (!getLocalFilename(configfilepath,includeNode->Attribute("file"),documentRef)) { return false; } ALLEGRO_PATH * incpath = al_create_path(configfilepath); al_append_path_component(incpath, "include"); TiXmlDocument doc( al_path_cstr(incpath, ALLEGRO_NATIVE_PATH_SEP) ); al_destroy_path(incpath); bool loadOkay = doc.LoadFile(); TiXmlHandle hDoc(&doc); TiXmlElement* elemParent; if(!loadOkay) { contentError("Include failed",includeNode); WriteErr("File load failed: %s\n",configfilepath); WriteErr("Line %d: %s\n",doc.ErrorRow(),doc.ErrorDesc()); return false; } elemParent = hDoc.FirstChildElement("include").Element(); if( elemParent == NULL) { contentError("Main <include> node not present",&doc); return false; } TiXmlElement* elemNode = elemParent->FirstChildElement(); if (elemNode == NULL) { contentError("Empty include",elemParent); return false; } while (elemNode) { if (!readNode(node, elemNode, elemParent, oldSibling)) return false; elemNode = elemNode->NextSiblingElement(); } return true; }
bool addSingleVegetationConfig( TiXmlElement* elemRoot, vector<VegetationConfiguration>* vegetationConfigs, vector<t_matgloss>& plantNames ) { const char* sheetIndexStr; t_SpriteWithOffset sprite; int basefile = -1; sprite.fileIndex=basefile; sprite.x=0; sprite.y=0; sprite.animFrames=ALL_FRAMES; const char* filename = elemRoot->Attribute("file"); if (filename != NULL && filename[0] != 0) { basefile = loadConfigImgFile((char*)filename, elemRoot); } //kinda round about- looking to needing to shift the lot into the plant elem sprite.fileIndex=basefile; TiXmlElement* elemTree; for (elemTree = elemRoot->FirstChildElement("plant"); elemTree; elemTree = elemTree->NextSiblingElement("plant") ){ const char* idstr = elemTree->Attribute("gameID"); int gameID = INVALID_INDEX; if (idstr && idstr[0]) { gameID = lookupIndexedType(idstr,plantNames); if (gameID == INVALID_INDEX) { contentError("No matching plant type",elemTree); continue; } } const char* deadstr = elemTree->Attribute("dead"); bool dead = (deadstr && deadstr[0]); const char* saplingstr = elemTree->Attribute("sapling"); bool sapling = (saplingstr && saplingstr[0]); sheetIndexStr = elemTree->Attribute("sheetIndex"); /* No animated trees. But we may repurpose it later to make a xyz variance? sprite.animFrames = getAnimFrames(elemProfession->Attribute("frames")); if (sprite.animFrames == 0) sprite.animFrames = ALL_FRAMES;*/ //create profession config sprite.sheetIndex=atoi(sheetIndexStr); VegetationConfiguration vegetationConfiguration(gameID, sprite, !dead, !sapling); //add a copy to known creatures vegetationConfigs->push_back( vegetationConfiguration ); } return true; }
bool includeFile(SpriteNode* node, TiXmlElement* includeNode, SpriteBlock* &oldSibling) { string filenameStr("buildings/include/"); filenameStr.append(includeNode->Attribute("file")); TiXmlDocument doc( filenameStr.c_str() ); bool loadOkay = doc.LoadFile(); TiXmlHandle hDoc(&doc); TiXmlElement* elemParent; if(!loadOkay) { contentError("Include failed",includeNode); WriteErr("File load failed: %s\n",filenameStr.c_str()); WriteErr("Line %d: %s\n",doc.ErrorRow(),doc.ErrorDesc()); return false; } elemParent = hDoc.FirstChildElement("include").Element(); if( elemParent == NULL) { contentError("Main <include> node not present",&doc); return false; } TiXmlElement* elemNode = elemParent->FirstChildElement(); if (elemNode == NULL) { contentError("Empty include",elemParent); return false; } while (elemNode) { if (!readNode(node, elemNode, elemParent, oldSibling)) return false; elemNode = elemNode->NextSiblingElement(); } return true; }
bool addCreaturesConfig( TiXmlElement* elemRoot, vector<vector<CreatureConfiguration>*>& knownCreatures ){ int basefile = -1; const char* filename = elemRoot->Attribute("file"); if (filename != NULL && filename[0] != 0) { basefile = loadConfigImgFile((char*)filename,elemRoot); } TiXmlElement* elemCreature = elemRoot->FirstChildElement("creature"); if (elemCreature == NULL) { contentError("No creatures found",elemRoot); return false; } while( elemCreature ){ addSingleCreatureConfig(elemCreature,knownCreatures,basefile ); elemCreature = elemCreature->NextSiblingElement("creature"); } return true; }
bool addSingleBuildingConfig( TiXmlElement* elemRoot, vector<BuildingConfiguration>* knownBuildings ){ const char* strName = elemRoot->Attribute("name"); const char* strGameID = elemRoot->Attribute("game_type"); const char* strGameSub = elemRoot->Attribute("game_subtype"); const char* strGameCustom = elemRoot->Attribute("game_custom"); if (strName == NULL || strGameID == NULL || strName[0] == 0 || strGameID[0] == 0) { contentError("<building> node must have name and game_type attributes",elemRoot); return false; } building_type::building_type main_type = (building_type::building_type) INVALID_INDEX; int subtype = INVALID_INDEX; string game_type_s; FOR_ENUM_ITEMS(building_type,i) { game_type_s = strGameID; if (game_type_s == ENUM_KEY_STR(building_type,i)) { main_type = i; break; } }
void parseWallFloorSpriteElement( TiXmlElement* elemWallFloorSprite, vector<TerrainConfiguration*>& configTable ,int basefile) { const char* spriteIndexStr = elemWallFloorSprite->Attribute("sprite"); if (spriteIndexStr == NULL || spriteIndexStr[0] == 0) { contentError("Invalid or missing sprite attribute",elemWallFloorSprite); return; //nothing to work with } // make a base sprite t_SpriteWithOffset sprite; sprite.sheetIndex=atoi(spriteIndexStr); sprite.fileIndex=basefile; sprite.x=0; sprite.y=0; sprite.animFrames=ALL_FRAMES; //augh! no animated terrains! please! // check for local file definitions const char* filename = elemWallFloorSprite->Attribute("file"); if (filename != NULL && filename[0] != 0) { sprite.fileIndex = loadConfigImgFile((char*)filename,elemWallFloorSprite); } vector<int> lookupKeys; // look through terrain elements TiXmlElement* elemTerrain = elemWallFloorSprite->FirstChildElement("terrain"); for(TiXmlElement* elemTerrain = elemWallFloorSprite->FirstChildElement("terrain"); elemTerrain; elemTerrain = elemTerrain->NextSiblingElement("terrain")) { //get a terrain type int targetElem=INVALID_INDEX; const char* gameIDstr = elemTerrain->Attribute("value"); if (gameIDstr == NULL || gameIDstr[0] == 0) { contentError("Invalid or missing value attribute",elemTerrain); continue; } targetElem = atoi (gameIDstr); //add it to the lookup vector lookupKeys.push_back(targetElem); if (configTable.size() <= (uint32_t)targetElem) { //increase size if needed configTable.resize(targetElem+1,NULL); } if (configTable[targetElem]==NULL) { // cleaned up in flushTerrainConfig configTable[targetElem] = new TerrainConfiguration(); } } // check we have some terrain types set int elems = (int)lookupKeys.size(); if (elems == 0) return; //nothing to link to // parse material elements TiXmlElement* elemMaterial = elemWallFloorSprite->FirstChildElement("material"); if (elemMaterial == NULL) { // if none, set default terrain sprites for each terrain type for (int i=0 ; i < elems; i++ ) { TerrainConfiguration *tConfig = configTable[lookupKeys[i]]; // if that was null we have *really* screwed up earlier // only update if not by previous configs if (tConfig->defaultSprite.sheetIndex == UNCONFIGURED_INDEX) { tConfig->defaultSprite = sprite; } } } for( ;elemMaterial;elemMaterial = elemMaterial->NextSiblingElement("material")) { // get material type int elemIndex = lookupMaterialType(elemMaterial->Attribute("value")); if (elemIndex == INVALID_INDEX) { contentError("Invalid or missing value attribute",elemMaterial); continue; } // parse subtype elements TiXmlElement* elemSubtype = elemMaterial->FirstChildElement("subtype"); if (elemSubtype == NULL) { // if none, set material default for each terrain type for (int i=0 ; i < elems; i++ ) { TerrainConfiguration *tConfig = configTable[lookupKeys[i]]; // if that was null we have *really* screwed up earlier // create a new TerrainMaterialConfiguration if required // make sure we have room for it first if (tConfig->terrainMaterials.size() <= (uint32_t)elemIndex) { // dont make a full size vector in advance- most of the time // we will only need the first few tConfig->terrainMaterials.resize(elemIndex+1,NULL); } if (tConfig->terrainMaterials[elemIndex] == NULL) { tConfig->terrainMaterials[elemIndex] = new TerrainMaterialConfiguration(); } // only update if not set by earlier configs if (tConfig->terrainMaterials[elemIndex]->defaultSprite.sheetIndex == UNCONFIGURED_INDEX) { tConfig->terrainMaterials[elemIndex]->defaultSprite = sprite; } } } for (;elemSubtype; elemSubtype = elemSubtype ->NextSiblingElement("subtype")) { // get subtype int subtypeId = lookupMaterialIndex(elemIndex,elemSubtype->Attribute("value")); if (subtypeId == INVALID_INDEX) { contentError("Invalid or missing value attribute",elemSubtype); continue; } // set subtype sprite for each terrain type for (int i=0 ; i < elems; i++ ) { TerrainConfiguration *tConfig = configTable[lookupKeys[i]]; //if that was null we have *really* screwed up earlier //create a new TerrainMaterialConfiguration if required //make sure we have room for it first if (tConfig->terrainMaterials.size() <= (uint32_t)elemIndex) { //dont make a full size vector in advance- we wont need it except //for those who insist on Soap Fortresses tConfig->terrainMaterials.resize(elemIndex+1,NULL); } if (tConfig->terrainMaterials[elemIndex] == NULL) { tConfig->terrainMaterials[elemIndex] = new TerrainMaterialConfiguration(); } // add to map (if not already present) map<int,t_SpriteWithOffset>::iterator it = tConfig->terrainMaterials[elemIndex]->overridingMaterials.find(subtypeId); if (it == tConfig->terrainMaterials[elemIndex]->overridingMaterials.end()) { tConfig->terrainMaterials[elemIndex]->overridingMaterials[subtypeId]=sprite; } } } } }
int parseConditionNode(ConditionalNode* node, TiXmlElement* elemCondition, bool silent){ const char* strType = elemCondition->Value(); BlockCondition* cond = NULL; if( strcmp(strType, "NeighbourWall") == 0){ cond = new NeighbourWallCondition( elemCondition->Attribute("dir") ); } else if( strcmp(strType, "PositionIndex") == 0){ cond = new PositionIndexCondition( elemCondition->Attribute("value") ); } else if( strcmp(strType, "MaterialType") == 0){ cond = new MaterialTypeCondition( elemCondition->Attribute("value") , elemCondition->Attribute("subtype")); } else if( strcmp(strType, "always") == 0){ cond = new AlwaysCondition(); } else if( strcmp(strType, "never") == 0){ cond = new NeverCondition(); } else if( strcmp(strType, "BuildingOccupancy") == 0){ cond = new BuildingOccupancyCondition( elemCondition->Attribute("value") ); } else if( strcmp(strType, "NeighbourSameBuilding") == 0){ cond = new NeighbourSameBuildingCondition( elemCondition->Attribute("dir") ); } else if( strcmp(strType, "NeighbourSameType") == 0){ cond = new NeighbourSameTypeCondition( elemCondition->Attribute("dir") ); } else if( strcmp(strType, "NeighbourOfType") == 0){ cond = new NeighbourOfTypeCondition( elemCondition->Attribute("dir") , elemCondition->Attribute("value") ); } else if( strcmp(strType, "NeighbourIdentical") == 0){ cond = new NeighbourIdenticalCondition( elemCondition->Attribute("dir") ); } else if( strcmp(strType, "AnimationFrame") == 0){ cond = new AnimationFrameCondition( elemCondition->Attribute("value") ); } else if( strcmp(strType, "FluidBelow") == 0){ cond = new FluidBelowCondition( elemCondition->Attribute("value") ); } else if( strcmp(strType, "HaveFloor") == 0){ cond = new HaveFloorCondition(); } else if( strcmp(strType, "and") == 0){ AndConditionalNode* andNode = new AndConditionalNode(); cond = andNode; if (!parseRecursiveNodes(andNode, elemCondition)) { delete(andNode); return 0; } } else if( strcmp(strType, "or") == 0){ OrConditionalNode* orNode = new OrConditionalNode(); cond = orNode; if (!parseRecursiveNodes(orNode, elemCondition)) { delete(orNode); return 0; } } else if( strcmp(strType, "not") == 0){ NotConditionalNode* notNode = new NotConditionalNode(); cond = notNode; if (!parseRecursiveNodes(notNode, elemCondition)) { delete(notNode); return 0; } } if (cond != NULL) { if (!node->addCondition( cond )) { contentError("Unable to add subcondition",elemCondition); delete(cond); return 0; } return 1; } else if (!silent) { contentError("Misplaced or invalid element in Condition",elemCondition); return 0; } return -1; }
inline bool readNode(SpriteNode* node, TiXmlElement* elemNode, TiXmlElement* elemParent, SpriteBlock* &oldSibling) { const char* strType = elemNode->Value(); if (strcmp(strType, "if") == 0 || strcmp(strType, "else") == 0) { SpriteBlock* block = new SpriteBlock(); if (!elemNode->Attribute("file") && elemParent->Attribute("file")) { elemNode->SetAttribute("file", elemParent->Attribute("file")); } if (!parseSpriteNode(block,elemNode)) { delete(block); return false; } if (elemNode->Attribute("else") || strcmp(strType, "else") == 0) { if (!oldSibling) { contentError("Misplaced or invalid element in SpriteNode",elemNode); return false; } oldSibling->addElse(block); } else { node->addChild(block); } oldSibling = block; } else if (strcmp(strType, "rotate") == 0) { RotationBlock* block = new RotationBlock(); if (!elemNode->Attribute("file") && elemParent->Attribute("file")) { elemNode->SetAttribute("file",elemParent->Attribute("file")); } if (!parseSpriteNode(block,elemNode)) { delete(block); return false; } else { node->addChild(block); } oldSibling = NULL; } else if ((strcmp(strType, "sprite") == 0) || (strcmp(strType, "empty") == 0)) { int fileindex = 0; const char* pfilename = elemParent->Attribute("file"); if (pfilename != NULL && pfilename[0] != 0) { fileindex = loadConfigImgFile((char*)pfilename,elemNode); } SpriteElement* sprite = new SpriteElement(); sprite->sprite.set_by_xml(elemNode, fileindex); node->addChild(sprite); } else if (strcmp(strType, "include") == 0) { if (!includeFile(node,elemNode,oldSibling)) { return false; } } else { contentError("Misplaced or invalid element in SpriteNode",elemNode); return false; } return true; }
void parseColorElement( TiXmlElement* elemColor, vector<ColorConfiguration> & configTable) { const char* colorRedStr = elemColor->Attribute("red"); if(colorRedStr == NULL || colorRedStr[0] == 0) { contentError("Invalid or missing color attribute",elemColor); return; //nothing to work with } const char* colorGreenStr = elemColor->Attribute("green"); if(colorGreenStr == NULL || colorGreenStr[0] == 0) { contentError("Invalid or missing color attribute",elemColor); return; //nothing to work with } const char* colorBlueStr = elemColor->Attribute("blue"); if(colorBlueStr == NULL || colorBlueStr[0] == 0) { contentError("Invalid or missing color attribute",elemColor); return; //nothing to work with } int red = atoi(colorRedStr); int green = atoi(colorGreenStr); int blue = atoi(colorBlueStr); ALLEGRO_COLOR color = al_map_rgb(red, green, blue); //parse material elements TiXmlElement* elemMaterial = elemColor->FirstChildElement("material"); if(elemMaterial == NULL) { //if none, there's nothing to be done with this color. contentError("Invalid or missing material attribute",elemColor); return; } for( ;elemMaterial;elemMaterial = elemMaterial->NextSiblingElement("material")) { // get material type int elemIndex = lookupMaterialType(elemMaterial->Attribute("value")); if (elemIndex == INVALID_INDEX) { contentError("Invalid or missing value attribute",elemMaterial); continue; } // parse subtype elements TiXmlElement* elemSubtype = elemMaterial->FirstChildElement("subtype"); if (elemSubtype == NULL) { // add the configurations if (configTable.size() <= (uint32_t)elemIndex) { //increase size if needed configTable.resize(elemIndex+1); } if(configTable.at(elemIndex).colorSet == false) { configTable.at(elemIndex).color = color; configTable.at(elemIndex).colorSet = true; } return; } for ( ;elemSubtype; elemSubtype = elemSubtype ->NextSiblingElement("subtype")) { // get subtype int subtypeId = lookupMaterialIndex( elemIndex,elemSubtype->Attribute("value")); if (subtypeId == INVALID_INDEX) { contentError("Invalid or missing value attribute",elemSubtype); continue; } // add the configurations if (configTable.size() <= (uint32_t)elemIndex) { //increase size if needed configTable.resize(elemIndex+1); } if (configTable.at(elemIndex).colorMaterials.size() <= (uint32_t)subtypeId) { //increase size if needed configTable.at(elemIndex).colorMaterials.resize(subtypeId+1); } if (configTable.at(elemIndex).colorMaterials.at(subtypeId).colorSet == false) { configTable.at(elemIndex).colorMaterials.at(subtypeId).color = color; configTable.at(elemIndex).colorMaterials.at(subtypeId).colorSet = true; } } } }
inline bool readNode(SpriteNode* node, TiXmlElement* elemNode, TiXmlElement* elemParent, SpriteBlock* &oldSibling) { const char* strType = elemNode->Value(); if (strcmp(strType, "if") == 0 || strcmp(strType, "else") == 0) { SpriteBlock* block = new SpriteBlock(); if (!elemNode->Attribute("file") && elemParent->Attribute("file")) { elemNode->SetAttribute("file", elemParent->Attribute("file")); } if (!parseSpriteNode(block,elemNode)) { delete(block); return false; } if (elemNode->Attribute("else") || strcmp(strType, "else") == 0) { if (!oldSibling) { contentError("Misplaced or invalid element in SpriteNode",elemNode); return false; } oldSibling->addElse(block); } else { node->addChild(block); } oldSibling = block; } else if (strcmp(strType, "rotate") == 0) { RotationBlock* block = new RotationBlock(); if (!elemNode->Attribute("file") && elemParent->Attribute("file")) { elemNode->SetAttribute("file",elemParent->Attribute("file")); } if (!parseSpriteNode(block,elemNode)) { delete(block); return false; } else { node->addChild(block); } oldSibling = NULL; } else if ((strcmp(strType, "sprite") == 0) || (strcmp(strType, "empty") == 0)) { SpriteElement* sprite = new SpriteElement(); const char* strSheetIndex = elemNode->Attribute("index"); const char* strOffsetX = elemNode->Attribute("offsetx"); const char* strOffsetY = elemNode->Attribute("offsety"); const char* filename = elemNode->Attribute("file"); getAnimFrames(elemNode->Attribute("frames")); sprite->sprite.animFrames = getAnimFrames(elemNode->Attribute("frames")); if (sprite->sprite.animFrames == 0) sprite->sprite.animFrames = ALL_FRAMES; sprite->sprite.sheetIndex = (strSheetIndex != 0 ? atoi(strSheetIndex) : -1); sprite->sprite.x = (strOffsetX != 0 ? atoi(strOffsetX) : 0); sprite->sprite.y = (strOffsetY != 0 ? atoi(strOffsetY) : 0); sprite->sprite.fileIndex = -1; if (filename != NULL && filename[0] != 0) { sprite->sprite.fileIndex = loadConfigImgFile((char*)filename,elemNode); } else { const char* pfilename = elemParent->Attribute("file"); if (pfilename != NULL && pfilename[0] != 0) { sprite->sprite.fileIndex = loadConfigImgFile((char*)pfilename,elemNode); } } node->addChild(sprite); } else if (strcmp(strType, "include") == 0) { if (!includeFile(node,elemNode,oldSibling)) { return false; } } else { contentError("Misplaced or invalid element in SpriteNode",elemNode); return false; } return true; }
void parseWallFloorSpriteElement( TiXmlElement* elemWallFloorSprite, vector<TerrainConfiguration*>& configTable ,int basefile, bool floor) { const char* spriteSheetIndexStr = elemWallFloorSprite->Attribute("sheetIndex"); const char* spriteSpriteStr = elemWallFloorSprite->Attribute("sprite"); const char* spriteIndexStr = elemWallFloorSprite->Attribute("index"); if ((spriteSheetIndexStr == NULL || spriteSheetIndexStr[0] == 0) && (spriteSpriteStr == NULL || spriteSpriteStr[0] == 0) && (spriteIndexStr == NULL || spriteIndexStr[0] == 0)) { contentError("Invalid or missing sprite attribute",elemWallFloorSprite); return; //nothing to work with } // make a base sprite c_sprite sprite; if(floor) { sprite.set_size(SPRITEWIDTH, (TILEHEIGHT + FLOORHEIGHT)); sprite.set_offset(0, (WALLHEIGHT)); } sprite.set_needoutline(1); sprite.set_by_xml(elemWallFloorSprite, basefile); vector<int> lookupKeys; // look through terrain elements TiXmlElement* elemTerrain = elemWallFloorSprite->FirstChildElement("terrain"); for(TiXmlElement* elemTerrain = elemWallFloorSprite->FirstChildElement("terrain"); elemTerrain; elemTerrain = elemTerrain->NextSiblingElement("terrain")) { //get a terrain type int targetElem=INVALID_INDEX; const char* gameIDstr = elemTerrain->Attribute("value"); if (gameIDstr == NULL || gameIDstr[0] == 0) { contentError("Invalid or missing value attribute",elemTerrain); continue; } targetElem = atoi (gameIDstr); //add it to the lookup vector lookupKeys.push_back(targetElem); if (configTable.size() <= (uint32_t)targetElem) { //increase size if needed configTable.resize(targetElem+1,NULL); } if (configTable[targetElem]==NULL) { // cleaned up in flushTerrainConfig configTable[targetElem] = new TerrainConfiguration(); } } // check we have some terrain types set int elems = (int)lookupKeys.size(); if (elems == 0) return; //nothing to link to vector<bool> formToggle; formToggle.resize(NUM_FORMS); // parse weather tile is for a block, log, etc TiXmlElement* elemForm = elemWallFloorSprite->FirstChildElement("form"); if(elemForm == NULL) { formToggle[0] = true; } for( ;elemForm;elemForm = elemForm->NextSiblingElement("form")) { const char * strForm = elemForm->Attribute("value"); if( strcmp(strForm, "bar") == 0) formToggle[FORM_BAR] = true; if( strcmp(strForm, "block") == 0) formToggle[FORM_BLOCK] = true; if( strcmp(strForm, "boulder") == 0) formToggle[FORM_BOULDER] = true; if( strcmp(strForm, "log") == 0) formToggle[FORM_LOG] = true; } // parse material elements TiXmlElement* elemMaterial = elemWallFloorSprite->FirstChildElement("material"); if (elemMaterial == NULL) { // if none, set default terrain sprites for each terrain type for (int i=0 ; i < elems; i++ ) { TerrainConfiguration *tConfig = configTable[lookupKeys[i]]; // if that was null we have *really* screwed up earlier // only update if not by previous configs for( int i = 0; i < NUM_FORMS; i++) { if(formToggle[i]) if (tConfig->defaultSprite[i].get_sheetindex() == UNCONFIGURED_INDEX) { tConfig->defaultSprite[i] = sprite; } } } } for( ;elemMaterial;elemMaterial = elemMaterial->NextSiblingElement("material")) { // get material type int elemIndex = lookupMaterialType(elemMaterial->Attribute("value")); if (elemIndex == INVALID_INDEX) { contentError("Invalid or missing value attribute",elemMaterial); continue; } // parse subtype elements TiXmlElement* elemSubtype = elemMaterial->FirstChildElement("subtype"); if (elemSubtype == NULL) { // if none, set material default for each terrain type for (int i=0 ; i < elems; i++ ) { TerrainConfiguration *tConfig = configTable[lookupKeys[i]]; // if that was null we have *really* screwed up earlier // create a new TerrainMaterialConfiguration if required // make sure we have room for it first if (tConfig->terrainMaterials.size() <= (uint32_t)elemIndex) { // dont make a full size vector in advance- most of the time // we will only need the first few tConfig->terrainMaterials.resize(elemIndex+1,NULL); } if (tConfig->terrainMaterials[elemIndex] == NULL) { tConfig->terrainMaterials[elemIndex] = new TerrainMaterialConfiguration(); } // only update if not set by earlier configs for( int i = 0; i < NUM_FORMS; i++) { if(formToggle[i]) if (tConfig->terrainMaterials[elemIndex]->defaultSprite[i].get_sheetindex() == UNCONFIGURED_INDEX) { tConfig->terrainMaterials[elemIndex]->defaultSprite[i] = sprite; } } } } for (;elemSubtype; elemSubtype = elemSubtype ->NextSiblingElement("subtype")) { // get subtype int subtypeId = lookupMaterialIndex(elemIndex,elemSubtype->Attribute("value")); if (subtypeId == INVALID_INDEX) { contentError("Invalid or missing value attribute",elemSubtype); continue; } // set subtype sprite for each terrain type for (int i=0 ; i < elems; i++ ) { TerrainConfiguration *tConfig = configTable[lookupKeys[i]]; //if that was null we have *really* screwed up earlier //create a new TerrainMaterialConfiguration if required //make sure we have room for it first if (tConfig->terrainMaterials.size() <= (uint32_t)elemIndex) { //dont make a full size vector in advance- we wont need it except //for those who insist on Soap Fortresses tConfig->terrainMaterials.resize(elemIndex+1,NULL); } if (tConfig->terrainMaterials[elemIndex] == NULL) { tConfig->terrainMaterials[elemIndex] = new TerrainMaterialConfiguration(); } // add to map (if not already present) for( int i = 0; i < NUM_FORMS; i++) { if(formToggle[i]) { map<int,c_sprite>::iterator it = tConfig->terrainMaterials[elemIndex]->overridingMaterials[i].find(subtypeId); if (it == tConfig->terrainMaterials[elemIndex]->overridingMaterials[i].end()) { tConfig->terrainMaterials[elemIndex]->overridingMaterials[i][subtypeId]=sprite; } } } } } } }