Esempio n. 1
0
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;
			}
		}
	}
}
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;
				}			
			} 			
		}
	}
}
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;
						}	
					}
				}
			} 			
		}
	}
}