void LocationEditor::AdvanceModeCameraMount()
{
  	if ( g_inputManager->controlEvent( ControlTileSelect ) )
	{
		CameraAnimSecondaryEditWindow *win = (CameraAnimSecondaryEditWindow*)
												EclGetWindow("editor_cameraanim");
		if (win && win->m_newNodeArmed)
		{
			Vector3 rayStart, rayDir;
			g_app->m_camera->GetClickRay( g_target->X(), 
										  g_target->Y(),
										  &rayStart, &rayDir );
			int mountId = DoesRayHitCameraMount(rayStart, rayDir);
			if (mountId != -1)
			{
				CameraMount *mount = g_app->m_location->m_levelFile->m_cameraMounts[mountId];
				AppDebugAssert(mount);
				
				CameraAnimation *anim = g_app->m_location->m_levelFile->m_cameraAnimations[m_selectionId];
				AppDebugAssert(anim);
				
				CamAnimNode *node = new CamAnimNode;
				node->m_mountName = strdup(mount->m_name);

				anim->m_nodes.PutData(node);

				win->m_newNodeArmed = false;
				win->RemoveButtons();
				win->AddButtons();
			}
		}
	}
}
void ScrollBarButton::MouseUp()
{    
    if( m_grabOffset == -1 )
    {

        AppDebugAssert( m_scrollBar );

        EclWindow *parent = EclGetWindow( m_scrollBar->m_parentWindow );
        AppDebugAssert( parent );

        int barTop = int( parent->m_y + m_y + m_h * (float) m_scrollBar->m_currentValue / (float) m_scrollBar->m_numRows );
        int barEnd = int( parent->m_y + m_y + m_h * (float) (m_scrollBar->m_currentValue + m_scrollBar->m_winSize) / (float) m_scrollBar->m_numRows );    
        if( barEnd >= m_h ) barEnd = m_h-1;

		int mouseY = g_target->Y();

        if( mouseY < barTop )
        {
            m_scrollBar->ChangeCurrentValue( -m_scrollBar->m_winSize );
        }
        else if( mouseY > barEnd )
        {
            m_scrollBar->ChangeCurrentValue( m_scrollBar->m_winSize );
        }

    }
    else
    {
        m_grabOffset = -1;
    }

}
void ScrollBarButton::MouseDown()
{
    if( m_grabOffset > -1 )
    {
        AppDebugAssert( m_scrollBar );
        int pixelsInside = g_target->Y() - ( m_parent->m_y + m_y );
        float fractionInside = (float) pixelsInside / (float) m_h;
        int centreVal = fractionInside * m_scrollBar->m_numRows;
        int desiredVal = centreVal - m_grabOffset;
        m_scrollBar->SetCurrentValue( desiredVal );
    }
    else
    {
        AppDebugAssert( m_scrollBar );
        EclWindow *parent = EclGetWindow( m_scrollBar->m_parentWindow );
        AppDebugAssert( parent );
        int mouseY = g_target->Y();
        int barTop = int( m_parent->m_y + m_y + m_h * (float) m_scrollBar->m_currentValue / (float) m_scrollBar->m_numRows );
        int barEnd = int( m_parent->m_y + m_y + m_h * (float) (m_scrollBar->m_currentValue + m_scrollBar->m_winSize) / (float) m_scrollBar->m_numRows );    
        //if( barEnd >= m_h ) barEnd = m_h-1;
        if( mouseY >= barTop && mouseY <= barEnd )
        {
            m_grabOffset = m_scrollBar->m_winSize * float( mouseY - barTop ) / float( barEnd - barTop );
        }
    }
}
double EntityBlueprint::GetStat( unsigned char _type, int _stat )
{
    AppDebugAssert( _type < Entity::NumEntityTypes );
    AppDebugAssert( _stat < Entity::NumStats );

	if (_stat == Entity::StatSpeed) 
	{
		if (_type != Entity::TypeSpaceInvader)
			return m_stats[_type][_stat] * (1.0 + (double) g_app->m_difficultyLevel / 10.0);
	}

    return m_stats[_type][_stat];
}
void WorldObjectId::Set( unsigned char _teamId,
                         int _unitId,
                         int _index,
                         int _uniqueId )
{
    AppDebugAssert( _teamId < ID_MAXTEAMS );
    AppDebugAssert( _unitId < ID_MAXUNITS );
    AppDebugAssert( _index < ID_MAXTROOPS );
    
    m_teamId = _teamId;
    m_unitId = _unitId;
    m_index = _index;
    m_uniqueId = _uniqueId;
}
void SoundLibrary3dDirectSound::SetChannelVolume( int _channel, float _volume )
{
	DirectSoundChannel *channel;
	if (_channel == m_musicChannelId) 
		channel = m_musicChannel;
	else				channel = &m_channels[_channel];

	if (!NearlyEquals(_volume, channel->m_volume) || m_forceVolumeUpdate )
	{
		AppDebugAssert(_volume >= 0.0f && _volume <= 10.0f);

		channel->m_volume = _volume;

//		long calculatedVolume = expf(10.0f - _volume);
//		calculatedVolume += m_masterVolume;
//		calculatedVolume *= -1.0f;

        float calculatedVolume = -(5.0f - _volume * 0.5f);
        calculatedVolume *= 1000.0f;
        calculatedVolume += m_masterVolume;

		if( calculatedVolume < -10000.0f ) calculatedVolume = -10000.0f;
		if( calculatedVolume > 0.0f ) calculatedVolume = 0.0f;

		IDirectSoundBuffer *buffer = channel->m_bufferInterface;
		int errCode = buffer->SetVolume( calculatedVolume );
		if (errCode == DSERR_BUFFERLOST)
			buffer->Restore();
		else
			SOUNDASSERT( errCode, "Direct sound couldn't set buffer volume" );
	}
}
Building::Building()
:   m_front(1,0,0),
    m_radius(13.0),
	m_timeOfDeath(-1.0),
	m_shape(NULL),
	m_dynamic(false),
	m_isGlobal(false),
	m_destroyed(false)
{
    if( !s_controlPad )
    {
        s_controlPad = g_app->m_resource->GetShape( "controlpad.shp" );
        AppDebugAssert( s_controlPad );

        const char controlPadStatusName[] = "MarkerStatus";
        s_controlPadStatus = s_controlPad->m_rootFragment->LookupMarker( controlPadStatusName );
        AppReleaseAssert( s_controlPadStatus, "Building: Can't get Marker(%s) from shape(%s), probably a corrupted file\n", controlPadStatusName, s_controlPad->m_name );
    }

    if( g_app->IsSinglePlayer() )
    {
        m_id.SetTeamId(1);
    }
    else
    {
        m_id.SetTeamId(255);
    }
    
    m_up = g_upVector;
}
char *Entity::GetTypeName( int _troopType )
{
    static char *typeNames[NumEntityTypes] = {
                                                "InvalidType",
                                                "LaserTroop",
                                                "Engineer",
                                                "Virii",
                                                "Squadie",
                                                "Egg",
                                                "SporeGenerator",
                                                "Lander",
												"Tripod",
                                                "Centipede",
                                                "SpaceInvader",
												"Spider",
                                                "Darwinian",
                                                "Officer",
                                                "ArmyAnt",
                                                "Armour",
                                                "SoulDestroyer",
                                                "TriffidEgg",
                                                "AI",
												"Shaman",
                                                "Harvester",
                                                "Nuke",
                                                "Tentacle",
                                                "Meteor",
                                                "Tank",
                                                "SpaceShip",
                                                "DropShip"
                                                };   

    AppDebugAssert( _troopType >= 0 && _troopType < NumEntityTypes );
    return typeNames[ _troopType ];
}
void SoundLibrary3dSoftware::EnableDspFX(int _channel, int _numFilters, int const *_filterTypes)
{
    AppReleaseAssert( _numFilters > 0, "Bad argument passed to EnableFilters" );

	SoftwareChannel *channel = &m_channels[_channel];
    for( int i = 0; i < _numFilters; ++i )
    {
		AppDebugAssert(_filterTypes[i] >= 0 && _filterTypes[i] < NUM_FILTERS);
		
		channel->m_dspFX[_filterTypes[i]].m_chainIndex = i;

		switch (_filterTypes[i])
		{
			case DSP_RESONANTLOWPASS:
				channel->m_dspFX[_filterTypes[i]].m_userFilter = new DspResLowPass(m_sampleRate);
				break;
			case DSP_BITCRUSHER:
				channel->m_dspFX[_filterTypes[i]].m_userFilter = new DspBitCrusher(m_sampleRate);
				break;
			case DSP_GARGLE:
				channel->m_dspFX[_filterTypes[i]].m_userFilter = new DspGargle(m_sampleRate);
				break;
			case DSP_ECHO:
				channel->m_dspFX[_filterTypes[i]].m_userFilter = new DspEcho(m_sampleRate);
				break;
			case DSP_SIMPLE_REVERB:
				channel->m_dspFX[_filterTypes[i]].m_userFilter = new DspReverb(m_sampleRate);
				break;
		}
    }
}
void LocationEditor::AdvanceModeLandFlat()
{
	Vector3 mousePos3D = g_app->m_userInput->GetMousePos3d();

	int newSelectionId = -1;
	if ( g_inputManager->controlEvent( ControlTileSelect ) )
	{
		Vector3 mousePos = g_app->m_userInput->GetMousePos3d();
		newSelectionId = IsPosInFlattenArea(mousePos);
	}

	if (m_selectionId == -1)
	{
		// If there isn't currently any selection, then check for a new one
		if (newSelectionId != -1)
		{
			m_selectionId = newSelectionId;
			m_waitingForRelease = true;
			
			EclWindow *cw = EclGetWindow("editor_landscape");
			AppDebugAssert(cw);
			LandscapeFlattenAreaEditWindow *ew = new LandscapeFlattenAreaEditWindow("Flatten Area", newSelectionId);
			ew->m_w = cw->m_w;
			ew->m_h = 100;
			ew->m_x = 0;
			EclRegisterWindow(ew);
			ew->m_y = cw->m_y - ew->m_h - 10;
		}
	}
	else
	{
		Location *location = g_app->m_location;

		if ( g_inputManager->controlEvent( ControlTileSelect ) )
		{
			if (newSelectionId == m_selectionId)
			{
				// The user "grabs" the landscape at this position
				LandscapeDef *landscapeDef = &(g_app->m_location->m_levelFile->m_landscape);
				LandscapeFlattenArea *areaDef = g_app->m_location->m_levelFile->m_landscape.m_flattenAreas.GetData(m_selectionId);
				m_landscapeGrabX = mousePos3D.x - areaDef->m_centre.x;
				m_landscapeGrabZ = mousePos3D.z - areaDef->m_centre.z;
			}
			else
			{
				// The user has deselected the flatten area
				m_selectionId = newSelectionId;
				m_waitingForRelease = true;
				EclRemoveWindow("Flatten Area");
			}
		}
		else if ( g_inputManager->controlEvent( ControlTileDrag ) )
		{
			// The user "drags" the flatten area around
			LandscapeFlattenArea *areaDef = g_app->m_location->m_levelFile->m_landscape.m_flattenAreas.GetData(m_selectionId);
			areaDef->m_centre.x = mousePos3D.x - m_landscapeGrabX;
			areaDef->m_centre.z = mousePos3D.z - m_landscapeGrabZ;
		}
	}
}
void SoundLib3dSoftwareCallbackWrapper(StereoSample *_buf, unsigned int _numSamples)
{
	AppDebugAssert(g_soundLibrary3d);
	SoundLibrary3dSoftware *lib = (SoundLibrary3dSoftware*)g_soundLibrary3d;
	if (lib)
		lib->Callback(_buf, _numSamples);
}
Example #12
0
int SoundInstanceCompare(const void *elem1, const void *elem2 )
{
    SoundInstanceId id1 = *((SoundInstanceId *) elem1);
    SoundInstanceId id2 = *((SoundInstanceId *) elem2);
    
    SoundInstance *instance1 = g_soundSystem->GetSoundInstance( id1 );
    SoundInstance *instance2 = g_soundSystem->GetSoundInstance( id2 );

    AppDebugAssert( instance1 );
    AppDebugAssert( instance2 );

    
    if      ( instance1->m_perceivedVolume < instance2->m_perceivedVolume )     return +1;
    else if ( instance1->m_perceivedVolume > instance2->m_perceivedVolume )     return -1;
    else                                                                        return 0;
}
void LandscapeRenderer::BuildUVArray(SurfaceMap2D <double> *_heightMap)
{
	if (m_verts.Size() <= 0)
		return;

	int nextUVId = 0;
	
    float factorX = 1.0 / _heightMap->m_cellSizeX;
    float factorZ = 1.0 / _heightMap->m_cellSizeY;

    for (int i = 0; i < m_strips.Size(); ++i)
	{
		LandTriangleStrip *strip = m_strips[i];
	
		int const numVerts = strip->m_numVerts;
		for (int j = 0; j < numVerts; ++j)
		{
			Vector3 const &vert = m_verts[strip->m_firstVertIndex + j].m_pos;
			float u = vert.x * factorX;
			float v = vert.z * factorZ;
			m_verts[nextUVId++].m_uv = TextureUV(u, v);
		}
	}

	AppDebugAssert(nextUVId == m_verts.NumUsed());
}
void LandscapeRenderer::Render()
{
	if (m_verts.Size() <= 0)
		return;

    g_app->m_location->SetupFog();
	glEnable		(GL_FOG);

	START_PROFILE( "Render Landscape Main");

	switch (m_renderMode) {
		case RenderModeDisplayList:
			{
				int id = g_app->m_resource->GetDisplayList(MAIN_DISPLAY_LIST_NAME);
				AppDebugAssert(id != -1);
				glCallList(id);
			}
			break;

		default:
			RenderMainSlow();
			break;
	}
	END_PROFILE( "Render Landscape Main");

    int landscapeDetail = 1;//g_prefsManager->GetInt( "RenderLandscapeDetail", 1 );
    if( landscapeDetail < 4 )
    {
	    START_PROFILE( "Render Landscape Overlay");
		switch (m_renderMode) {
			case RenderModeDisplayList:
				{
					int id = g_app->m_resource->GetDisplayList(OVERLAY_DISPLAY_LIST_NAME);
					AppDebugAssert(id != -1);
					glCallList(id);
				}
				break;

			default:
			    RenderOverlaySlow();
				;
	    }
	    END_PROFILE( "Render Landscape Overlay");
    }
    
    glDisable		(GL_FOG);
}
void SoundLibrary3dDirectSound::ResetChannel( int _channel )
{    
	DirectSoundChannel *channel;
	bool isMusicChannel = false;
	if (_channel == m_musicChannelId) 
	{
		isMusicChannel = true;
		channel = m_musicChannel;
	}
	else
	{
		channel = &m_channels[_channel];
	}

    int errCode;


	AppDebugAssert(_channel >= -1);


	//
    // Get Play Cursor

    unsigned long playCursor;
    unsigned long writeCursor;
    errCode = channel->m_bufferInterface->GetCurrentPosition(&playCursor, &writeCursor);
	if (errCode == DSERR_BUFFERLOST)
		errCode = channel->m_bufferInterface->Restore();
    else
		SOUNDASSERT(errCode, "Direct sound couldn't get current position");
	
	if (errCode == DSERR_BUFFERLOST)
		return;

	//
    // Find out where we can write our samples
   
    int firstSample = writeCursor/2;
    int playCursorAhead = playCursor/2;
    if( playCursor/2 < firstSample )
    {
        playCursorAhead += channel->m_numBufferSamples;
    }
    int numSamples = playCursorAhead - firstSample - 1;
    if( firstSample >= channel->m_numBufferSamples )
    {
        firstSample -= channel->m_numBufferSamples;
    }


	//
    // Populate our buffer

    if (numSamples > 0)
    {           
		PopulateBuffer( _channel, firstSample, numSamples, isMusicChannel );
		channel->m_channelHealth = 1.0f;
    }
}
void SoundLibrary3dDirectSound::Verify()
{
	for (int i = 0; i < m_numChannels; ++i)
	{
		int numFilters = GetNumFilters(i);
		AppDebugAssert(numFilters <= 1);
	}
}
void LandscapeRenderer::BuildColourArray()
{
	if (m_verts.Size() <= 0)
		return;

	int nextColId = 0;

	for (int i = 0; i < m_strips.Size(); ++i)
	{
		LandTriangleStrip *strip = m_strips[i];
	
		m_verts[nextColId++].m_col.Set(255,0,255);
		m_verts[nextColId++].m_col.Set(255,0,255);

		int const numVerts = strip->m_numVerts - 2;
		for (int j = 0; j < numVerts; ++j)
		{
			Vector3 const &v1 = m_verts[strip->m_firstVertIndex + j].m_pos;
			Vector3 const &v2 = m_verts[strip->m_firstVertIndex + j + 1].m_pos;
			Vector3 const &v3 = m_verts[strip->m_firstVertIndex + j + 2].m_pos;
			Vector3 centre = (v1 + v2 + v3) * 0.33333;
			Vector3 const &norm = m_verts[strip->m_firstVertIndex + j + 2].m_norm;
			RGBAColour col;
			GetLandscapeColour(centre.y, norm.y, 
							   (unsigned int)centre.x, (unsigned int)centre.z, 
							   &col);

            for( int i = 0; i < g_app->m_location->m_burnPatches.Size(); ++i )
            {
                BurnPatch *patch = g_app->m_location->m_burnPatches.GetPointer(i);
                double dist = (centre - patch->m_pos).Mag();
                if( dist < patch->m_radius * 1.5 )
                {
                    RGBAColour burnCol(20, 20, 20);
                    double ratio = 0.0;
                    if( dist > patch->m_radius / 2.0 )
                    {
                        ratio = (dist - (patch->m_radius / 2.0)) / patch->m_radius;
                        //ratio *= 0.5;
                        ratio = min( 1.0, ratio );
                    }
                    col = (col * ratio ) + (burnCol * (1.0 -ratio));
                }
            }

			//AppDebugOut("%d[%d]: r:%02x g:%02x b:%02x a:%02x\n", i, j,  col.r, col.g, col.b, col.a);
#ifdef USE_DIRECT3D
			D3DCOLOR d3dCol = D3DCOLOR_ARGB(col.a, col.r, col.g, col.b);
			memcpy(&m_verts[nextColId++].m_col, &d3dCol, sizeof(d3dCol));
#else
			m_verts[nextColId++].m_col = col;
#endif
		}
	}

	AppDebugAssert(nextColId == m_verts.NumUsed());
}
Bridge::Bridge()
:   Teleport(),
    m_nextBridgeId(-1),
    m_status(0.0),
    m_signal(NULL),
    m_beingOperated(false)
{
    m_type = Building::TypeBridge;
    m_sendPeriod = BRIDGE_TRANSPORTPERIOD;

    m_shapes[0] = g_app->m_resource->GetShape( "bridgeend.shp" );
    m_shapes[1] = g_app->m_resource->GetShape( "bridgetower.shp" );

    AppDebugAssert( m_shapes[0] );
    AppDebugAssert( m_shapes[1] );
    
    SetBridgeType( BridgeTypeTower );
}
void LandscapeRenderer::BuildNormArray()
{
	if (m_verts.Size() <= 0)
		return;

	int nextNormId = 0;

	// Go through all the strips...
	for (int i = 0; i < m_strips.Size(); ++i)
	{
		LandTriangleStrip *strip = m_strips[i];

		m_verts[nextNormId++].m_norm = g_upVector;
		m_verts[nextNormId++].m_norm = g_upVector;
		int const maxJ = strip->m_numVerts - 2;
		
		// For each vertex in strip
		for (int j = 0; j < maxJ; j += 2)
		{
			Vector3 const &v1 = m_verts[strip->m_firstVertIndex + j].m_pos;
			Vector3 const &v2 = m_verts[strip->m_firstVertIndex + j + 1].m_pos;
			Vector3 const &v3 = m_verts[strip->m_firstVertIndex + j + 2].m_pos;
			Vector3 const &v4 = m_verts[strip->m_firstVertIndex + j + 3].m_pos;

			Vector3 north(v1 - v2);
			Vector3 northEast(v3 - v2);
			Vector3 east(v4 - v2);

			Vector3 norm1(northEast ^ north);
			norm1.Normalise();
			Vector3 norm2(east ^ northEast);
			norm2.Normalise();

			m_verts[nextNormId++].m_norm = norm1;
			m_verts[nextNormId++].m_norm = norm2;

			int vertIndex = strip->m_firstVertIndex + j + 2;
			AppDebugAssert(nextNormId - 2 == vertIndex);
		}
	}

	int vertIndex = m_verts.NumUsed();
	AppDebugAssert(nextNormId == vertIndex);
}
Example #20
0
char *SoundParameter::GetUpdateTypeName( int _type )
{
    char *names[] = { 
                        "UpdateConstantly",
                        "UpdateOncePerLoop"
                    };

    AppDebugAssert( _type >= 0 && _type < NumUpdateTypes );
    return names[ _type ];
}
Example #21
0
char *SoundParameter::GetLinkName( int _type )
{
    if( _type == -1 ) return "Nothing";

    LList<char *> properties;
    g_soundSystem->m_interface->ListProperties( &properties );

    AppDebugAssert( _type >= 0 && _type < properties.Size() );
    return properties[_type];
}
void LocationEditor::AdvanceModeInstantUnit()
{
	Camera *cam = g_app->m_camera;

	int newSelectionId = -1;
	if ( g_inputManager->controlEvent( ControlTileSelect ) ) // TODO: Should be something else?
	{
		Vector3 rayStart, rayDir;
		cam->GetClickRay( g_target->X(), g_target->Y(), &rayStart, &rayDir );
		newSelectionId = DoesRayHitInstantUnit(rayStart, rayDir);
	}

	if (m_selectionId == -1)
	{
		if (newSelectionId != -1)
		{
			m_selectionId = newSelectionId;
			EclWindow *cw = EclGetWindow("editor_instantunits");
			AppDebugAssert(cw);
			InstantUnitEditWindow *ew = new InstantUnitEditWindow("editor_instantuniteditor");
			ew->m_w = cw->m_w;
			ew->m_h = 160;
			ew->m_x = cw->m_x;
			EclRegisterWindow(ew);
			ew->m_y = cw->m_y - ew->m_h - 10;
			m_waitingForRelease = true;
		}
	}
	else 
	{
		if ( g_inputManager->controlEvent( ControlTileSelect ) ) // TODO: Something else?
		{
			if (newSelectionId != m_selectionId)
			{
				m_selectionId = -1;
				EclRemoveWindow("editor_instantuniteditor");
			}
		}
		else if ( g_inputManager->controlEvent( ControlTileDrag ) ) // TODO: Something else?
		{
			InstantUnit *iu = g_app->m_location->m_levelFile->m_instantUnits.GetData(m_selectionId);
			switch (m_tool)
			{
				case ToolMove:
				{
					Vector3 mousePos = g_app->m_userInput->GetMousePos3d();
					iu->m_posX = mousePos.x;
					iu->m_posZ = mousePos.z;
					break;
				}
			}
		}
	}
}
Example #23
0
char *SoundParameter::GetParameterTypeName( int _type )
{
    char *names[] = {   
                        "TypeFixedValue",
                        "TypeRangedRandom",
                        "TypeLinked"
                    };

    AppDebugAssert( _type >= 0 && _type < NumParameterTypes );
    return names[_type];
}
int Entity::EnterTeleports( int _requiredId )
{
    LList<int> *buildings = g_app->m_location->m_obstructionGrid->GetBuildings( m_pos.x, m_pos.z );
    
    for( int i = 0; i < buildings->Size(); ++i )
    {
        int buildingId = buildings->GetData(i);
        if( _requiredId != -1 && _requiredId != buildingId )
        {
            // We are only permitted to enter building with id _requiredId
            continue;
        }

        Building *building = g_app->m_location->GetBuilding( buildingId );
        AppDebugAssert( building );
        
        if( building->m_type == Building::TypeRadarDish  )
        {
            RadarDish *radarDish = (RadarDish *) building;
            Vector3 entrancePos, entranceFront;
            radarDish->GetEntrance( entrancePos, entranceFront );
            double range = ( m_pos - entrancePos ).Mag();
            if( radarDish->ReadyToSend() &&                             
                range < 15.0 &&
                m_front * entranceFront < 0.0 )
            {
                WorldObjectId id(m_id);
                radarDish->EnterTeleport( id );
                g_app->m_soundSystem->TriggerEntityEvent( this, "EnterTeleport" );
                return buildingId;
            }
        }
        else if( building->m_type == Building::TypeBridge )
        {
            Bridge *bridge = (Bridge *) building;
            Vector3 entrancePos, entranceFront;
            if( bridge->GetEntrance( entrancePos, entranceFront ) )
            {
                double range = ( m_pos - bridge->m_pos ).Mag();
                if( bridge->ReadyToSend() &&
                    range < 25.0 &&
                    m_front * entranceFront < 0.0 )
                {
                    WorldObjectId id( m_id );
                    bridge->EnterTeleport( id );
                    g_app->m_soundSystem->TriggerEntityEvent( this, "EnterTeleport" );
                    return buildingId;
                }
            }
        }        
    }

    return -1;
}
ScrollBar::ScrollBar( EclWindow *parent )
:   m_x(0),
    m_y(0),
    m_w(0),
    m_h(0),
    m_numRows(0),
    m_winSize(0),
    m_currentValue(0)
{
    AppDebugAssert( parent );
    strcpy( m_parentWindow, parent->m_name );
    strcpy( m_name, "New Scrollbar" );
}
void SoundLibrary3dDirectSound::DisableDspFX( int _channel )
{
    int errCode;

	AppDebugAssert(GetNumFilters(_channel) > 0);

   	DirectSoundChannel *channel;
	if (_channel == m_musicChannelId) channel = m_musicChannel;
	else				channel = &m_channels[_channel];

	IDirectSoundBuffer8 *buffer = (IDirectSoundBuffer8 *) channel->m_bufferInterface;

	
    //
    // Stop the channel

    errCode = buffer->Stop();
    SOUNDASSERT( errCode, "Direct sound couldn't stop a secondary buffer" );

    
    //
    // Shut down the filters

	int numDxFilters = 0;
	for (int i = 0; i < NUM_FILTERS; ++i)
	{
		SoundLibFilter *filter = &channel->m_dspFX[i];
		if (filter->m_userFilter != NULL)
		{
			delete filter->m_userFilter; 
            filter->m_userFilter = NULL;
		}
		else if (filter->m_dxFilter)
		{
			numDxFilters++;
		}
		filter->m_dxFilter = false;
	}
	if (numDxFilters > 0)
	{
		errCode = buffer->SetFX( 0, NULL, NULL );
        SOUNDASSERT( errCode, "Direct sound couldn't set fx" );
	}

    
    //
    // Restart the channel

    errCode = buffer->Play( 0, 0,  DSBPLAY_LOOPING );
    SOUNDASSERT( errCode, "Direct sound couldn't play a secondary buffer" );    
}
void Entity::FollowRoute()
{
	AppDebugAssert(m_routeId != -1);
	Route *route = g_app->m_location->m_levelFile->GetRoute(m_routeId);
    
    if( g_app->Multiplayer() ) route = g_app->m_location->m_routingSystem.GetRoute( m_routeId );

	if(!route)
    {
        m_routeId = -1;
        return;
    }

	if (m_routeWayPointId == -1)
	{
		m_routeWayPointId = 0;
	}

    WayPoint *waypoint = route->m_wayPoints.GetData(m_routeWayPointId);
    if( !waypoint )
    {
        m_routeId = -1;
        return;
    }

    SetWaypoint ( waypoint->GetPos() );
	Vector3 targetVect = waypoint->GetPos() - m_pos;

	m_spawnPoint = waypoint->GetPos();

    if (waypoint->m_type != WayPoint::TypeBuilding &&
        targetVect.Mag() < m_routeTriggerDistance )
	{

		m_routeWayPointId++;
		if (m_routeWayPointId >= route->m_wayPoints.Size())
		{
			m_routeWayPointId = -1;
			m_routeId = -1;
		}
	}

    //
    // If its a building instead of a 3D pos, this unit will never
    // get to the next waypoint.  A new unit is created when the unit
    // enters the teleport, and taht new unit will automatically
    // continue towards the next waypoint instead.
    //
}
Entity *Entity::NewEntity( int _troopType )
{
    Entity *entity = NULL;

    switch(_troopType)
    {
        case Entity::TypeLaserTroop:            entity = new LaserTrooper();        break;
        case Entity::TypeInsertionSquadie:      entity = new Squadie();             break;
        case Entity::TypeEngineer:              entity = new Engineer();            break;            
        case Entity::TypeVirii:                 entity = new Virii();               break;
        case Entity::TypeEgg:                   entity = new Egg();                 break;
        case Entity::TypeSporeGenerator:        entity = new SporeGenerator();      break;
        case Entity::TypeLander:                entity = new Lander();              break;
		case Entity::TypeTripod:				entity = new Tripod();				break;
        case Entity::TypeCentipede:             entity = new Centipede();           break;
        case Entity::TypeSpaceInvader:          entity = new SpaceInvader();        break;
		case Entity::TypeSpider:				entity = new Spider();				break;
        case Entity::TypeDarwinian:             entity = new Darwinian();           break;
        case Entity::TypeOfficer:               entity = new Officer();             break;
        case Entity::TypeArmyAnt:               entity = new ArmyAnt();             break;
        case Entity::TypeArmour:                entity = new Armour();              break;
        case Entity::TypeSoulDestroyer:         entity = new SoulDestroyer();       break;
        case Entity::TypeTriffidEgg:            entity = new TriffidEgg();          break;
        case Entity::TypeAI:                    entity = new AI();                  break;
		case Entity::TypeShaman:				entity = new Shaman();				break;
        case Entity::TypeHarvester:             entity = new Harvester();           break;
        case Entity::TypeNuke:                  entity = new Nuke();                break;
        case Entity::TypeTentacle:              entity = new Tentacle();            break;
        case Entity::TypeMeteor:                entity = new Meteor();              break;
        case Entity::TypeTank:                  entity = new Tank();                break;
        case Entity::TypeSpaceShip:             entity = new SpaceShip();           break;
        case Entity::TypeDropShip:              entity = new DropShip();            break;

        default:                                AppDebugAssert(false);
    }
    
    entity->m_id.GenerateUniqueId();

#ifdef TRACK_SYNC_RAND
	void TrackEntity( Entity *_entity );
    TrackEntity( entity );
#endif

    return entity;
}
bool SoulDestroyer::SearchForRetreatPosition()
{
    WorldObjectId targetId = g_app->m_location->m_entityGrid->GetBestEnemy( m_pos.x, m_pos.z, 0.0, SOULDESTROYER_MAXSEARCHRANGE, m_id.GetTeamId() );
    
    if( targetId.IsValid() )
    {
        WorldObject *obj = g_app->m_location->GetEntity( targetId );
        AppDebugAssert( obj );

        double distance = 50.0;
        Vector3 retreatVector = ( m_pos - obj->m_pos ).Normalise();
        double angle = syncsfrand( M_PI * 1.0 );
        retreatVector.RotateAroundY( angle );
        m_targetPos = m_pos + retreatVector * distance;
        m_targetPos.y = min( m_targetPos.y, 300.0 );
        return true;
    }
     
    return false;
}
void ScrollBarButton::Render( int realX, int realY, bool highlighted, bool clicked )
{
    
    AppDebugAssert( m_scrollBar );

    // Background

    glColor3ub( 85, 93, 78 );
    glBegin( GL_QUADS );
        glVertex2i( realX, realY );
        glVertex2i( realX + m_w, realY );
        glVertex2i( realX + m_w, realY + m_h );
        glVertex2i( realX, realY + m_h );
    glEnd();

    glColor3ub( 187, 187, 187 );
    glBegin( GL_LINE_LOOP );
        glVertex2i( realX, realY );
        glVertex2i( realX + m_w, realY );
        glVertex2i( realX + m_w, realY + m_h );
        glVertex2i( realX, realY + m_h );
    glEnd();
    
    // Bar
    int barTop = int( m_h * (float) m_scrollBar->m_currentValue / (float) m_scrollBar->m_numRows);
    int barEnd = int( m_h * (float) (m_scrollBar->m_currentValue + m_scrollBar->m_winSize) / (float) m_scrollBar->m_numRows );    
    if( barEnd >= m_h ) barEnd = m_h-1;


    if( clicked )           glColor3ub(50,55,120);
    else if( highlighted )  glColor3ub(55,60,120);
    else                    glColor3ub(65,71,120);
        
    glBegin( GL_QUADS );
        glVertex2i( realX+1, realY+barTop+1 );
        glVertex2i( realX+m_w, realY+barTop+1 );
        glVertex2i( realX+m_w, realY+barEnd);
        glVertex2i( realX+1, realY+barEnd);
    glEnd();
}