コード例 #1
0
ファイル: terrain.cpp プロジェクト: BG1/warzone2100
/// Set up the texture coordinates for a tile
static void getTileTexCoords(Vector2f *uv, unsigned int tileNumber)
{
	/* unmask proper values from compressed data */
	const unsigned short texture = TileNumber_texture(tileNumber);
	const unsigned short tile = TileNumber_tile(tileNumber);

	/* Used to calculate texture coordinates */
	const float xMult = 1.0f / TILES_IN_PAGE_COLUMN;
	const float yMult = 1.0f / TILES_IN_PAGE_ROW;
	float texsize = (float)getTextureSize();
	float centertile, shiftamount, one;
	Vector2f sP1, sP2, sP3, sP4, sPTemp;

	// the decals are 128x128 (at this time), we should not go above this value.  See note above
	if (texsize > MAX_TILE_TEXTURE_SIZE)
	{
		texsize = MAX_TILE_TEXTURE_SIZE;
	}
	centertile = 0.5f / texsize;			//compute center of tile
	shiftamount = (texsize -1.0) / texsize;	// 1 pixel border
	one = 1.0f / (TILES_IN_PAGE_COLUMN * texsize);

	// bump the texture coords, for 1 pixel border, so our range is [.5,(texsize - .5)]
	one += centertile * shiftamount;
	/*
	 * Points for flipping the texture around if the tile is flipped or rotated
	 * Store the source rect as four points
	 */
	sP1.x = one;
	sP1.y = one;
	sP2.x = xMult - one;
	sP2.y = one;
	sP3.x = xMult - one;
	sP3.y = yMult - one;
	sP4.x = one;
	sP4.y = yMult - one;

	if (texture & TILE_XFLIP)
	{
		sPTemp = sP1;
		sP1 = sP2;
		sP2 = sPTemp;

		sPTemp = sP3;
		sP3 = sP4;
		sP4 = sPTemp;
	}
	if (texture & TILE_YFLIP)
	{
		sPTemp = sP1;
		sP1 = sP4;
		sP4 = sPTemp;
		sPTemp = sP2;
		sP2 = sP3;
		sP3 = sPTemp;
	}

	switch ((texture & TILE_ROTMASK) >> TILE_ROTSHIFT)
	{
		case 1:
			sPTemp = sP1;
			sP1 = sP4;
			sP4 = sP3;
			sP3 = sP2;
			sP2 = sPTemp;
			break;
		case 2:
			sPTemp = sP1;
			sP1 = sP3;
			sP3 = sPTemp;
			sPTemp = sP4;
			sP4 = sP2;
			sP2 = sPTemp;
			break;
		case 3:
			sPTemp = sP1;
			sP1 = sP2;
			sP2 = sP3;
			sP3 = sP4;
			sP4 = sPTemp;
			break;
	}
	uv[0 + 0].x = tileTexInfo[tile].uOffset + sP1.x;
	uv[0 + 0].y = tileTexInfo[tile].vOffset + sP1.y;
	
	uv[0 + 2].x = tileTexInfo[tile].uOffset + sP2.x;
	uv[0 + 2].y = tileTexInfo[tile].vOffset + sP2.y;
	
	uv[1 + 2].x = tileTexInfo[tile].uOffset + sP3.x;
	uv[1 + 2].y = tileTexInfo[tile].vOffset + sP3.y;
	
	uv[1 + 0].x = tileTexInfo[tile].uOffset + sP4.x;
	uv[1 + 0].y = tileTexInfo[tile].vOffset + sP4.y;
}
コード例 #2
0
ファイル: terrain.cpp プロジェクト: Warzone2100/warzone2100
/// Set up the texture coordinates for a tile
static Vector2f getTileTexCoords(Vector2f *uv, unsigned int tileNumber)
{
	/* unmask proper values from compressed data */
	const unsigned short texture = TileNumber_texture(tileNumber);
	const unsigned short tile = TileNumber_tile(tileNumber);

	/* Used to calculate texture coordinates */
	const float xMult = 1.0f / TILES_IN_PAGE_COLUMN;
	const float yMult = 1.0f / TILES_IN_PAGE_ROW;
	float texsize = (float)getTextureSize();

	// the decals are 128x128 (at this time), we should not go above this value.  See note above
	if (texsize > MAX_TILE_TEXTURE_SIZE)
	{
		texsize = MAX_TILE_TEXTURE_SIZE;
	}
	const float centertile = 0.5f / texsize;	// compute center of tile
	const float shiftamount = (texsize - 1.0) / texsize;	// 1 pixel border
	// bump the texture coords, for 1 pixel border, so our range is [.5,(texsize - .5)]
	const float one = 1.0f / (TILES_IN_PAGE_COLUMN * texsize) + centertile * shiftamount;

	/*
	 * Points for flipping the texture around if the tile is flipped or rotated
	 * Store the source rect as four points
	 */
	Vector2f sP1 { one, one };
	Vector2f sP2 { xMult - one, one };
	Vector2f sP3 { xMult - one, yMult - one };
	Vector2f sP4 { one, yMult - one };

	if (texture & TILE_XFLIP)
	{
		std::swap(sP1, sP2);
		std::swap(sP3, sP4);
	}
	if (texture & TILE_YFLIP)
	{
		std::swap(sP1, sP4);
		std::swap(sP2, sP3);
	}

	Vector2f sPTemp;
	switch ((texture & TILE_ROTMASK) >> TILE_ROTSHIFT)
	{
	case 1:
		sPTemp = sP1;
		sP1 = sP4;
		sP4 = sP3;
		sP3 = sP2;
		sP2 = sPTemp;
		break;
	case 2:
		sPTemp = sP1;
		sP1 = sP3;
		sP3 = sPTemp;
		sPTemp = sP4;
		sP4 = sP2;
		sP2 = sPTemp;
		break;
	case 3:
		sPTemp = sP1;
		sP1 = sP2;
		sP2 = sP3;
		sP3 = sP4;
		sP4 = sPTemp;
		break;
	}
	const Vector2f offset { tileTexInfo[tile].uOffset, tileTexInfo[tile].vOffset };

	uv[0 + 0] = offset + sP1;
	uv[0 + 2] = offset + sP2;
	uv[1 + 2] = offset + sP3;
	uv[1 + 0] = offset + sP4;

	/// Calculate the average texture coordinates of 4 points
	return Vector2f { (uv[0].x + uv[1].x + uv[2].x + uv[3].x) / 4, (uv[0].y + uv[1].y + uv[2].y + uv[3].y) / 4 };
}
コード例 #3
0
ファイル: feature.c プロジェクト: blezek/warzone2100
/* Remove a Feature and free it's memory */
bool destroyFeature(FEATURE *psDel)
{
	UDWORD			widthScatter,breadthScatter,heightScatter, i;
	EFFECT_TYPE		explosionSize;
	Vector3i pos;
	UDWORD			width,breadth;
	UDWORD			mapX,mapY;

	ASSERT_OR_RETURN(false, psDel != NULL, "Invalid feature pointer");

 	/* Only add if visible and damageable*/
	if(psDel->visible[selectedPlayer] && psDel->psStats->damageable)
	{
		/* Set off a destruction effect */
		/* First Explosions */
		widthScatter = TILE_UNITS/2;
		breadthScatter = TILE_UNITS/2;
		heightScatter = TILE_UNITS/4;
		//set which explosion to use based on size of feature
		if (psDel->psStats->baseWidth < 2 && psDel->psStats->baseBreadth < 2)
		{
			explosionSize = EXPLOSION_TYPE_SMALL;
		}
		else if (psDel->psStats->baseWidth < 3 && psDel->psStats->baseBreadth < 3)
		{
			explosionSize = EXPLOSION_TYPE_MEDIUM;
		}
		else
		{
			explosionSize = EXPLOSION_TYPE_LARGE;
		}
		for(i=0; i<4; i++)
		{
			pos.x = psDel->pos.x + widthScatter - rand()%(2*widthScatter);
			pos.z = psDel->pos.y + breadthScatter - rand()%(2*breadthScatter);
			pos.y = psDel->pos.z + 32 + rand()%heightScatter;
			addEffect(&pos,EFFECT_EXPLOSION,explosionSize,false,NULL,0);
		}

		if(psDel->psStats->subType == FEAT_SKYSCRAPER)
		{
			pos.x = psDel->pos.x;
			pos.z = psDel->pos.y;
			pos.y = psDel->pos.z;
			addEffect(&pos,EFFECT_DESTRUCTION,DESTRUCTION_TYPE_SKYSCRAPER,true,psDel->sDisplay.imd,0);
			initPerimeterSmoke(psDel->sDisplay.imd, pos);

			shakeStart();
		}

		/* Then a sequence of effects */
		pos.x = psDel->pos.x;
		pos.z = psDel->pos.y;
		pos.y = map_Height(pos.x,pos.z);
		addEffect(&pos,EFFECT_DESTRUCTION,DESTRUCTION_TYPE_FEATURE,false,NULL,0);

		//play sound
		// ffs gj
		if(psDel->psStats->subType == FEAT_SKYSCRAPER)
		{
			audio_PlayStaticTrack( psDel->pos.x, psDel->pos.y, ID_SOUND_BUILDING_FALL );
		}
		else
		{
			audio_PlayStaticTrack( psDel->pos.x, psDel->pos.y, ID_SOUND_EXPLOSION );
		}
	}

	if (psDel->psStats->subType == FEAT_SKYSCRAPER)
	{
		// ----- Flip all the tiles under the skyscraper to a rubble tile
		// smoke effect should disguise this happening
		mapX = map_coord(psDel->pos.x) - psDel->psStats->baseWidth/2;
		mapY = map_coord(psDel->pos.y) - psDel->psStats->baseBreadth/2;
		for (width = 0; width < psDel->psStats->baseWidth; width++)
		{
			for (breadth = 0; breadth < psDel->psStats->baseBreadth; breadth++)
			{
				MAPTILE *psTile = mapTile(mapX+width,mapY+breadth);
				// stops water texture chnaging for underwateer festures
				if (terrainType(psTile) != TER_WATER)
				{
					if (terrainType(psTile) != TER_CLIFFFACE)
					{
						/* Clear feature bits */
						psTile->texture = TileNumber_texture(psTile->texture) | RUBBLE_TILE;
					}
					else
					{
						/* This remains a blocking tile */
						psTile->psObject = NULL;
						psTile->texture = TileNumber_texture(psTile->texture) | BLOCKING_RUBBLE_TILE;
					}
				}
			}
		}
	}

	removeFeature(psDel);
	return true;
}
コード例 #4
0
ファイル: feature.cpp プロジェクト: Mailaender/warzone2100
/* Remove a Feature and free it's memory */
bool destroyFeature(FEATURE *psDel, unsigned impactTime)
{
	UDWORD			widthScatter, breadthScatter, heightScatter, i;
	EFFECT_TYPE		explosionSize;
	Vector3i pos;

	ASSERT_OR_RETURN(false, psDel != NULL, "Invalid feature pointer");
	ASSERT(gameTime - deltaGameTime < impactTime, "Expected %u < %u, gameTime = %u, bad impactTime", gameTime - deltaGameTime, impactTime, gameTime);

	/* Only add if visible and damageable*/
	if (psDel->visible[selectedPlayer] && psDel->psStats->damageable)
	{
		/* Set off a destruction effect */
		/* First Explosions */
		widthScatter = TILE_UNITS / 2;
		breadthScatter = TILE_UNITS / 2;
		heightScatter = TILE_UNITS / 4;
		//set which explosion to use based on size of feature
		if (psDel->psStats->baseWidth < 2 && psDel->psStats->baseBreadth < 2)
		{
			explosionSize = EXPLOSION_TYPE_SMALL;
		}
		else if (psDel->psStats->baseWidth < 3 && psDel->psStats->baseBreadth < 3)
		{
			explosionSize = EXPLOSION_TYPE_MEDIUM;
		}
		else
		{
			explosionSize = EXPLOSION_TYPE_LARGE;
		}
		for (i = 0; i < 4; i++)
		{
			pos.x = psDel->pos.x + widthScatter - rand() % (2 * widthScatter);
			pos.z = psDel->pos.y + breadthScatter - rand() % (2 * breadthScatter);
			pos.y = psDel->pos.z + 32 + rand() % heightScatter;
			addEffect(&pos, EFFECT_EXPLOSION, explosionSize, false, NULL, 0, impactTime);
		}

		if (psDel->psStats->subType == FEAT_SKYSCRAPER)
		{
			pos.x = psDel->pos.x;
			pos.z = psDel->pos.y;
			pos.y = psDel->pos.z;
			addEffect(&pos, EFFECT_DESTRUCTION, DESTRUCTION_TYPE_SKYSCRAPER, true, psDel->sDisplay.imd, 0, impactTime);
			initPerimeterSmoke(psDel->sDisplay.imd, pos);

			shakeStart(250);	// small shake
		}

		/* Then a sequence of effects */
		pos.x = psDel->pos.x;
		pos.z = psDel->pos.y;
		pos.y = map_Height(pos.x, pos.z);
		addEffect(&pos, EFFECT_DESTRUCTION, DESTRUCTION_TYPE_FEATURE, false, NULL, 0, impactTime);

		//play sound
		// ffs gj
		if (psDel->psStats->subType == FEAT_SKYSCRAPER)
		{
			audio_PlayStaticTrack(psDel->pos.x, psDel->pos.y, ID_SOUND_BUILDING_FALL);
		}
		else
		{
			audio_PlayStaticTrack(psDel->pos.x, psDel->pos.y, ID_SOUND_EXPLOSION);
		}
	}

	if (psDel->psStats->subType == FEAT_SKYSCRAPER)
	{
		// ----- Flip all the tiles under the skyscraper to a rubble tile
		// smoke effect should disguise this happening
		StructureBounds b = getStructureBounds(psDel);
		for (int breadth = 0; breadth < b.size.y; ++breadth)
		{
			for (int width = 0; width < b.size.x; ++width)
			{
				MAPTILE *psTile = mapTile(b.map.x + width, b.map.y + breadth);
				// stops water texture changing for underwater features
				if (terrainType(psTile) != TER_WATER)
				{
					if (terrainType(psTile) != TER_CLIFFFACE)
					{
						/* Clear feature bits */
						psTile->texture = TileNumber_texture(psTile->texture) | RUBBLE_TILE;
						auxClearBlocking(b.map.x + width, b.map.y + breadth, AUXBITS_ALL);
					}
					else
					{
						/* This remains a blocking tile */
						psTile->psObject = NULL;
						auxClearBlocking(b.map.x + width, b.map.y + breadth, AIR_BLOCKED);  // Shouldn't remain blocking for air units, however.
						psTile->texture = TileNumber_texture(psTile->texture) | BLOCKING_RUBBLE_TILE;
					}
				}
			}
		}
	}

	removeFeature(psDel);
	psDel->died = impactTime;
	return true;
}