Exemple #1
0
void CRoomTemplate::LoadFromKeyValues( const char *pRoomName, KeyValues *pKeyValues )
{
    m_nTilesX = pKeyValues->GetInt( "TilesX", 1 );
    m_nTilesY = pKeyValues->GetInt( "TilesY", 1 );
    SetSpawnWeight( pKeyValues->GetInt( "SpawnWeight", MIN_SPAWN_WEIGHT ) );

    SetFullName( pRoomName );

    Q_strncpy( m_Description, pKeyValues->GetString( "RoomTemplateDescription", "" ), m_nMaxDescriptionLength );
    Q_strncpy( m_Soundscape, pKeyValues->GetString( "Soundscape", "" ), m_nMaxSoundscapeLength );

    SetTileType( pKeyValues->GetInt( "TileType", ASW_TILETYPE_UNKNOWN ) );

    m_Tags.RemoveAll();

    // search through all the exit subsections
    KeyValues *pkvSubSection = pKeyValues->GetFirstSubKey();
    bool bClearedExits = false;
    while ( pkvSubSection )
    {
        // mission details
        if ( Q_stricmp(pkvSubSection->GetName(), "EXIT")==0 )
        {
            if ( !bClearedExits )
            {
                // if we haven't cleared previous exits yet then do so now
                m_Exits.PurgeAndDeleteElements();
                bClearedExits = true;
            }
            CRoomTemplateExit *pExit = new CRoomTemplateExit();
            pExit->m_iXPos = pkvSubSection->GetInt("XPos");
            pExit->m_iYPos = pkvSubSection->GetInt("YPos");
            pExit->m_ExitDirection = (ExitDirection_t) pkvSubSection->GetInt("ExitDirection");
            pExit->m_iZChange = pkvSubSection->GetInt("ZChange");
            Q_strncpy( pExit->m_szExitTag, pkvSubSection->GetString( "ExitTag" ), sizeof( pExit->m_szExitTag ) );
            pExit->m_bChokepointGrowSource = !!pkvSubSection->GetInt("ChokeGrow", 0);

            // discard exits outside the room bounds
            if ( pExit->m_iXPos < 0 || pExit->m_iYPos < 0 || pExit->m_iXPos >= m_nTilesX || pExit->m_iYPos >= m_nTilesY )
            {
                delete pExit;
            }
            else
            {
                m_Exits.AddToTail(pExit);
            }
        }
        else if ( Q_stricmp(pkvSubSection->GetName(), "Tags")==0 && TagList() )
        {
            for ( KeyValues *sub = pkvSubSection->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() )
            {
                if ( !Q_stricmp( sub->GetName(), "tag" ) )
                {
                    AddTag( sub->GetString() );
                }
            }
        }
        pkvSubSection = pkvSubSection->GetNextKey();
    }
}
Exemple #2
0
void CEnvironmentGrid::CreateSquareNebula (SCreateCtx &Ctx, TArray<STileDesc> *retTiles)

//	CreateSquareNebula
//
//	The nebula is a square:
//
//	center: Ctx.pOrbitDesc position
//	height: Ctx.rHeight
//	width: Ctx.rWidth

	{
	if (Ctx.pEnv == NULL || Ctx.pOrbitDesc == NULL || Ctx.rWidth == 0.0 || Ctx.rHeight == 0.0)
		return;

	CVector vCenter = Ctx.pOrbitDesc->GetObjectPos();

	//	Compute the bounds of the nebula

	CVector vUL = vCenter + CVector(-0.5 * Ctx.rWidth, -0.5 * Ctx.rHeight);
	CVector vLR = vCenter + CVector(0.5 * Ctx.rWidth, 0.5 * Ctx.rHeight);

	//	Now iterate over every tile in bounds and see if it is within
	//	the band that we have defined.

	int xTileStart, yTileStart, xTileEnd, yTileEnd;
	VectorToTile(vUL, &xTileStart, &yTileStart);
	VectorToTile(vLR, &xTileEnd, &yTileEnd);

	//	Set the granularity of the result array (so that we don't keep on
	//	reallocating).

	if (retTiles)
		{
		retTiles->DeleteAll();
		int iGranularity = Max(DEFAULT_ARRAY_GRANULARITY, (xTileEnd - xTileStart + 1) * (yTileEnd - yTileStart + 1) / 2);
		retTiles->SetGranularity(iGranularity);
		}

	//	Set all tiles

	int x, y;
	for (x = xTileStart; x <= xTileEnd; x++)
		for (y = yTileStart; y <= yTileEnd; y++)
			{
			SetTileType(x, y, Ctx.pEnv);

			//	Add to list of tiles

			if (retTiles)
				{
				STileDesc *pNewTile = retTiles->Insert();
				pNewTile->x = x;
				pNewTile->y = y;
				pNewTile->pEnv = Ctx.pEnv;
				pNewTile->dwEdgeMask = 0;
				}
			}
	}
Exemple #3
0
void CEnvironmentGrid::ConvertSpaceEnvironmentToPointers (CTileMap &UNIDs)

//	ConvertSpaceEnvironmentToPointers
//
//	Converts m_pEnvironment to pointers (restore from save file)

	{
	m_Map.Init(UNIDs.GetSize(), UNIDs.GetScale());

	STileMapEnumerator k;
	while (UNIDs.HasMore(k))
		{
		DWORD dwTile;
		int xTile;
		int yTile;

		UNIDs.GetNext(k, &xTile, &yTile, &dwTile);
		CSpaceEnvironmentType *pEnv = g_pUniverse->FindSpaceEnvironment(dwTile);
		if (pEnv)
			SetTileType(xTile, yTile, pEnv);
		}

	m_iTileCount = m_Map.GetTotalSize();
	}
Exemple #4
0
void CEnvironmentGrid::CreateArcNebula (SCreateCtx &Ctx, TArray<STileDesc> *retTiles)

//	CreateArcNebula
//
//	Creates an arc of nebula

	{
	if (Ctx.pEnv == NULL || Ctx.pOrbitDesc == NULL || Ctx.rWidth == 0.0)
		return;

	//	Compute some constants

	Metric rHalfWidth = Ctx.rWidth / 2.0;
	Metric rMaxVariation = Ctx.iWidthVariation * rHalfWidth / 100.0;
	Metric rHalfVariation = rMaxVariation / 2.0;
	Metric rHalfSpan = g_Pi * Ctx.iSpan / 360.0;

	//	Shape of the arc

	CVector vCenter = Ctx.pOrbitDesc->GetFocus();
	Metric rArcCenterAngle = Ctx.pOrbitDesc->GetObjectAngle();
	Metric rMaxRadius = Ctx.pOrbitDesc->GetSemiMajorAxis() + rHalfWidth;
	Metric rMinRadius = Ctx.pOrbitDesc->GetSemiMajorAxis() - rHalfWidth;

	//	Shape parameters

	CWaveGenerator2 OuterWave(
			0.75,	//	Wave 0 amplitude
			5.0,	//	Wave 0 cycles
			0.25,	//	Wave 1 amplitude
			11.0	//	Wave 1 cycles
			);

	CWaveGenerator2 InnerWave(
			0.5,
			6.0,
			0.5,
			15.0
			);

	//	Compute the bounds of the nebula

	Metric rDiag = rMaxRadius + (GetTileSize() * g_KlicksPerPixel);
	CVector vUL = vCenter + CVector(-rDiag, rDiag);
	CVector vLR = vCenter + CVector(rDiag, -rDiag);

	//	Now iterate over every tile in bounds and see if it is within
	//	the band that we have defined.

	int xTileStart, yTileStart, xTileEnd, yTileEnd;
	VectorToTile(vUL, &xTileStart, &yTileStart);
	VectorToTile(vLR, &xTileEnd, &yTileEnd);

	//	Set the granularity of the result array (so that we don't keep on
	//	reallocating).

	if (retTiles)
		{
		retTiles->DeleteAll();
		int iGranularity = Max(DEFAULT_ARRAY_GRANULARITY, (xTileEnd - xTileStart + 1) * (yTileEnd - yTileStart + 1) / 2);
		retTiles->SetGranularity(iGranularity);
		}

	//	Set all tiles

	int x, y;
	for (x = xTileStart; x <= xTileEnd; x++)
		for (y = yTileStart; y <= yTileEnd; y++)
			{
			CVector vTile = TileToVector(x, y);
			CVector vRadius = vTile - vCenter;

			//	Convert to polar coordinates

			Metric rRadius;
			Metric rAngle = VectorToPolarRadians(vRadius, &rRadius);

			//	Skip if outside bounds

			if (rRadius > rMaxRadius || rRadius < rMinRadius)
				continue;

			//	Figure out our distance from the center angle

			Metric rDistAngle = rAngle - rArcCenterAngle;
			if (rDistAngle > g_Pi)
				rDistAngle -= 2.0 * g_Pi;
			else if (rDistAngle < -g_Pi)
				rDistAngle += 2.0 * g_Pi;

			Metric rDistAngleAbs = Absolute(rDistAngle);
			if (rDistAngleAbs > rHalfSpan)
				continue;

			//	Compute the shape at this angle

			Metric rMidRadius;
			Ctx.pOrbitDesc->GetPointAndRadius(rAngle, &rMidRadius);

			Metric rOuterWave = rHalfVariation * OuterWave.GetValue(rAngle);
			Metric rInnerWave = rHalfVariation * InnerWave.GetValue(rAngle);

			//	Taper the shape

			Metric rTaper = 1.0 - (rDistAngleAbs / rHalfSpan);

			//	Calc radius

			Metric rOuterRadius = rMidRadius + rTaper * (rHalfWidth - rOuterWave);
			Metric rInnerRadius = rMidRadius - rTaper * (rHalfWidth + rInnerWave);

			//	If we're inside the ring, then put a nebula down

			if (rRadius > rInnerRadius && rRadius < rOuterRadius)
				{
				SetTileType(x, y, Ctx.pEnv);

				//	Add to list of tiles

				if (retTiles)
					{
					STileDesc *pNewTile = retTiles->Insert();
					pNewTile->x = x;
					pNewTile->y = y;
					pNewTile->pEnv = Ctx.pEnv;
					pNewTile->dwEdgeMask = 0;
					}
				}
			}
	}
Exemple #5
0
void CEnvironmentGrid::CreateCircularNebula (SCreateCtx &Ctx, TArray<STileDesc> *retTiles)

//	CreateCircularNebula
//
//	The nebula is a ring:
//
//	radius: Ctx.pOrbitDesc radius
//	width of ring: Ctx.rWidth

	{
	if (Ctx.pEnv == NULL || Ctx.pOrbitDesc == NULL || Ctx.rWidth == 0.0)
		return;

	//	Compute some constants

	Metric rHalfWidth = Ctx.rWidth / 2.0;
	Metric rMaxVariation = Ctx.iWidthVariation * rHalfWidth / 100.0;
	Metric rHalfVariation = rMaxVariation / 2.0;

	//	Shape parameters

	CWaveGenerator2 OuterWave(
			0.75,	//	Wave 0 amplitude
			5.0,	//	Wave 0 cycles
			0.25,	//	Wave 1 amplitude
			11.0	//	Wave 1 cycles
			);

	CWaveGenerator2 InnerWave(
			0.5,
			6.0,
			0.5,
			15.0
			);

	//	The maximum diameter of the ring is the orbit diameter plus half the
	//	width.

	Metric rMaxRadius = Ctx.pOrbitDesc->GetSemiMajorAxis() + rHalfWidth;
	CVector vCenter = Ctx.pOrbitDesc->GetFocus();

	//	Compute the bounds of the nebula

	Metric rDiag = rMaxRadius + (GetTileSize() * g_KlicksPerPixel);
	CVector vUL = vCenter + CVector(-rDiag, rDiag);
	CVector vLR = vCenter + CVector(rDiag, -rDiag);

	//	Now iterate over every tile in bounds and see if it is within
	//	the band that we have defined.

	int xTileStart, yTileStart, xTileEnd, yTileEnd;
	VectorToTile(vUL, &xTileStart, &yTileStart);
	VectorToTile(vLR, &xTileEnd, &yTileEnd);

	//	Set the granularity of the result array (so that we don't keep on
	//	reallocating).

	if (retTiles)
		{
		retTiles->DeleteAll();
		int iGranularity = Max(DEFAULT_ARRAY_GRANULARITY, (xTileEnd - xTileStart + 1) * (yTileEnd - yTileStart + 1) / 2);
		retTiles->SetGranularity(iGranularity);
		}

	//	Set all tiles

	int x, y;
	for (x = xTileStart; x <= xTileEnd; x++)
		for (y = yTileStart; y <= yTileEnd; y++)
			{
			CVector vTile = TileToVector(x, y);
			CVector vRadius = vTile - vCenter;

			//	Convert to polar coordinates

			Metric rRadius;
			Metric rAngle = VectorToPolarRadians(vRadius, &rRadius);

			//	Compute the shape at this angle

			Metric rMidRadius;
			Ctx.pOrbitDesc->GetPointAndRadius(rAngle, &rMidRadius);

			Metric rOuterWave = rHalfVariation * OuterWave.GetValue(rAngle);
			Metric rInnerWave = rHalfVariation * InnerWave.GetValue(rAngle);

			Metric rOuterRadius = rMidRadius + rHalfWidth - rOuterWave;
			Metric rInnerRadius = rMidRadius - rHalfWidth + rInnerWave;

			//	If we're inside the ring, then put a nebula down

			if (rRadius > rInnerRadius && rRadius < rOuterRadius)
				{
				SetTileType(x, y, Ctx.pEnv);

				//	Add to list of tiles

				if (retTiles)
					{
					STileDesc *pNewTile = retTiles->Insert();
					pNewTile->x = x;
					pNewTile->y = y;
					pNewTile->pEnv = Ctx.pEnv;
					pNewTile->dwEdgeMask = 0;
					}
				}
			}
	}