void CItemCommCrystal::OnMoveFrom()
{
	// Being removed from the top level.
	CSector * pSector = GetTopPoint().GetSector();
	ASSERT(pSector);
	pSector->RemoveListenItem();
}
Exemple #2
0
/// Funktion erteilt einen Terraformbefehl, sofern dies auch möglich ist.
/// @param pShip Zeiger des Schiffes
/// @return <code>true</code> wenn ein Terraformbefehl gegeben werden könnte
bool CShipAI::DoTerraform(CShips* pShip)
{
	if (!pShip)
	{
		ASSERT(pShip);
		return false;
	}

	// Es wird jeder Planet sofort genommen, welcher weniger als 8 Runden zum Terraformen
	// benötigt. Planeten welche mehr Runden zum Terraformen benötigen werden nur ausgewählt,
	// wenn in dem Sektor kein Planet zum sofortigen Kolonisieren zur Verfügung steht

	int nTerraPoints = pShip->GetColonizePoints();
	if (nTerraPoints <= 0)
		return false;

	CSector* pSector = &m_pDoc->GetSector(pShip->GetKO().x, pShip->GetKO().y);
	// nur wenn der Sektor noch niemandem gehört bzw. uns selbst ist, sollen Planeten terraformt werden
	if (pSector->GetOwnerOfSector() != "" && pSector->GetOwnerOfSector() != pShip->GetOwnerOfShip())
		return false;

	int nMinTerraPoints = INT_MAX;
	short nPlanet = -1;

	bool bColonizable = false;
	for (int j = 0; j < pSector->GetNumberOfPlanets(); j++)
	{
		const CPlanet* pPlanet = pSector->GetPlanet(j);
		// Planet überhaupt bewohnbar?
		if (!pPlanet->GetHabitable())
			continue;

		// Planet schon terraformt?
		if (pPlanet->GetTerraformed())
		{
			// und noch nicht kolonisiert?
			if (!pPlanet->GetColonized())
				bColonizable = true;
		}
		else if (pPlanet->GetNeededTerraformPoints() < nMinTerraPoints)
		{
			nMinTerraPoints = pPlanet->GetNeededTerraformPoints();
			nPlanet = j;
		}
	}

	// Wurde ein zu terraformender Planet gefunden und würden weniger als 6 Runden
	// zum Terraformen benötigt werden oder es gibt keinen Planeten, der
	// sofort kolonisiert werden könnte, dann den gefundenen Planeten terraformen
	if (nPlanet != -1 && (!bColonizable || nMinTerraPoints / nTerraPoints < 8))
	{
		// Hier muss als erstes ein möglicher neuer Kurs gelöscht werden
		pShip->SetTargetKO(CPoint(-1, -1));
		pShip->SetTerraform(nPlanet);

		return true;
	}

	return false;
}
Exemple #3
0
bool CRegionBase::RealizeRegion()
{
	ADDTOCALLSTACK("CRegionBase::RealizeRegion");
	// Link the region to the world. RETURN: false = not valid.
	if ( IsRegionEmpty() )
		return false;
	if ( !m_pt.IsValidPoint() )
		m_pt = GetRegionCorner( DIR_QTY );	// center

	// Attach to all sectors that i overlap.
	ASSERT( m_iLinkedSectors == 0 );
	for ( long l = 0; l < g_MapList.GetSectorQty(m_pt.m_map); l++ )
	{
		CSector *pSector = g_World.GetSector(m_pt.m_map, l);

		if ( pSector && IsOverlapped(pSector->GetRect()) )
		{
			//	Yes, this sector overlapped, so add it to the sector list
			if ( !pSector->LinkRegion(this) )
			{
				g_Log.EventError("Linking sector #%ld for map %d for region %s failed (fatal for this region).\n", l, m_pt.m_map, GetName());
				return false;
			}
			m_iLinkedSectors++;
		}
	}
	return true;
}
Exemple #4
0
void CSector::GoAwake()
{
    ADDTOCALLSTACK("CSector::GoAwake");
    ProfileTask charactersTask(PROFILE_TIMERS);
    CTimedObject::GoAwake();  // Awake it first, otherwise other things won't work.

    CChar * pCharNext = nullptr;
    CChar * pChar = static_cast <CChar*>(m_Chars_Active.GetHead());
    for (; pChar != nullptr; pChar = pCharNext)
    {
        pCharNext = pChar->GetNext();
        if (pChar->IsSleeping())
            pChar->GoAwake();
    }

    pChar = static_cast<CChar*>(m_Chars_Disconnect.GetHead());
    for (; pChar != nullptr; pChar = pCharNext)
    {
        pCharNext = pChar->GetNext();
        if (pChar->IsSleeping())
            pChar->GoAwake();
    }

    CItem * pItemNext = nullptr;
    CItem * pItem = static_cast <CItem*>(m_Items_Timer.GetHead());
    for (; pItem != nullptr; pItem = pItemNext)
    {
        pItemNext = pItem->GetNext();
		if (pItem->IsSleeping())
        	pItem->GoAwake();
    }
    pItem = static_cast <CItem*>(m_Items_Inert.GetHead());
    for (; pItem != nullptr; pItem = pItemNext)
    {
        pItemNext = pItem->GetNext();
        if (pItem->IsSleeping())
			pItem->GoAwake();
    }

    /*
    * Awake adjacent sectors when awaking this one to avoid the effect
    * of NPCs being stop until you enter the sector, or all the spawns
    * generating NPCs at once.
    */
    static CSector *pCentral = nullptr;   // do this only for the awaken sector
    if (!pCentral)
    {
        pCentral = this;  
        for (int i = 0; i < (int)DIR_QTY; ++i)
        {
            CSector *pSector = GetAdjacentSector((DIR_TYPE)i);
            if (pSector && !pSector->IsSleeping())
            {
                pSector->GoAwake();
            }
        }
        pCentral = nullptr;
    }
    OnTick();   // Unknown time passed, make the sector tick now to reflect any possible environ changes.
}
Exemple #5
0
void CItemCommCrystal::OnMoveFrom()
{
	ADDTOCALLSTACK("CItemCommCrystal::OnMoveFrom");
	// Being removed from the top level.
	CSector *pSector = GetTopSector();
	if ( pSector )
		pSector->RemoveListenItem();
}
Exemple #6
0
void __fastcall TfraSector::ebCaptureInsideVolumeClick(TObject *Sender)
{
	CSector* S = PortalUtils.GetSelectedSector();
	if (S){
    	S->CaptureInsideVolume();
        Scene->UndoSave();
    }
}
Exemple #7
0
// Move this item to it's point in the world. (ground/top level)
bool CItemCommCrystal::MoveTo(CPointMap pt, bool bForceFix)
{
	ADDTOCALLSTACK("CItemCommCrystal::MoveTo");
	CSector *pSector = pt.GetSector();
	ASSERT(pSector);
	pSector->AddListenItem();
	return CItem::MoveTo(pt, bForceFix);
}
Exemple #8
0
void __fastcall TfraSector::ebDistributeObjectsClick(TObject *Sender)
{
	CSector* S = PortalUtils.GetSelectedSector();
	if (S){
    	S->DistributeInsideObjects	();
        Scene->UndoSave				();
    }
}
bool CItemCommCrystal::MoveTo( CPointMap pt ) // Put item on the ground here.
{
	// Move this item to it's point in the world. (ground/top level)
	CSector * pSector = pt.GetSector();
	ASSERT(pSector);
	pSector->AddListenItem();
	return CItem::MoveTo(pt);
}
Exemple #10
0
bool CItemCommCrystal::MoveTo(CPointMap pt, bool bForceFix ) // Put item on the ground here.
{
	ADDTOCALLSTACK("CItemCommCrystal::MoveTo");
	// Move this item to it's point in the world. (ground/top level)
	CSector * pSector = pt.GetSector();
	ASSERT(pSector);
	pSector->AddListenItem();
	return CItem::MoveTo(pt, bForceFix);
}
Exemple #11
0
bool CTeleport::RealizeTeleport()
{
	ADDTOCALLSTACK("CTeleport::RealizeTeleport");
	if ( !IsValidPoint() || !m_ptDst.IsValidPoint() )
	{
		DEBUG_ERR(("Bad teleport coords %s\n", WriteUsed()));
		return false;
	}
	CSector *pSector = GetSector();
	return pSector ? pSector->AddTeleport(this) : false;
}
//////new version database read and save
bool CAirportsManager::loadDatabase(CAirportDatabase* pAirportDatabase)
{
	ASSERT(pAirportDatabase);
	if(!pAirportDatabase)
		return false;

	Clear();

	CString strSQL(_T(""));
	CADORecordset adoAirportRecordset;
	long lCount = 0 ;
	strSQL.Format(_T("SELECT * FROM TB_AIRPORTDB_AIRPORT"));
	try
	{
		CDatabaseADOConnetion::ExecuteSQLStatement(strSQL,lCount,adoAirportRecordset,pAirportDatabase->GetAirportConnection()) ;
	}
	catch (CADOException& e)
	{
		e.ErrorMessage();
		return false;
	}

	while(!adoAirportRecordset.IsEOF())
	{
		 CAirport* pAirport = new CAirport;
		 pAirport->loadDatabase(adoAirportRecordset);
		 m_vAirports.push_back(pAirport);
		 adoAirportRecordset.MoveNextData();
	}

	//read all sector
	CADORecordset adoSectorRecordset;
	strSQL.Format(_T("SELECT * FROM TB_AIRPORTDB_SECTOR"));
	try
	{
		CDatabaseADOConnetion::ExecuteSQLStatement(strSQL,lCount,adoSectorRecordset,pAirportDatabase->GetAirportConnection());
	}
	catch (CADOException& e)
	{
		e.ErrorMessage();
		return false;
	}
	
	while(!adoSectorRecordset.IsEOF())
	{
		CSector* pSector = new CSector(this);
		pSector->loadDatabase(adoSectorRecordset,pAirportDatabase);
		m_vSectors.push_back(pSector);
		adoSectorRecordset.MoveNextData();
	}

	return true;
}
Exemple #13
0
size_t CPointBase::GetRegions( DWORD dwType, CRegionLinks & rlinks ) const
{
	ADDTOCALLSTACK("CPointBase::GetRegions");
	if ( !IsValidPoint() )
		return 0;

	CSector *pSector = GetSector();
	if ( pSector )
		return pSector->GetRegions(*this, dwType, rlinks);

	return 0;
}
void CAirportsManager::AddSector(CString sSectorName, CAIRPORTFILTER airportFilter)
{
	for(unsigned i=0; i<m_vSectors.size(); i++) {
		CSector* pSector = m_vSectors[i];
		if(pSector->m_sName.Compare(sSectorName) == 0) { //found sector
			pSector->AddFilter(airportFilter);
			return;
		}
	}
	CSector* pSector = new CSector( this );
	pSector->m_sName = sSectorName;
	pSector->AddFilter(airportFilter);
	m_vSectors.push_back(pSector);
}
Exemple #15
0
bool CTeleport::RealizeTeleport()
{
	ADDTOCALLSTACK("CTeleport::RealizeTeleport");
	if ( ! IsCharValid() || ! m_ptDst.IsCharValid())
	{
		DEBUG_ERR(( "CTeleport bad coords %s\n", WriteUsed() ));
		return false;
	}
	CSector *pSector = GetSector();
	if ( pSector )
		return pSector->AddTeleport(this);
	else
		return false;
}
Exemple #16
0
bool CFat32Device::ReadFromCache(unsigned long sector, unsigned char *buffer)
{
  // round sector size down to page size
  unsigned long page = sector & ~(FAT_PAGE_SIZE / m_sectorsize - 1);
  FATCACHE::iterator it = m_cache.find(page);
  if (it != m_cache.end())
  {
    cacheHit++;
    CSector *cacheSector = (*it).second;
    cacheSector->IncrementUsage(timeGetTime());
    fast_memcpy(buffer, cacheSector->Get() + (sector - page)*m_sectorsize, m_sectorsize);
    return true;
  }
  return false;
}
Exemple #17
0
CRegionBase * CPointBase::GetRegion( DWORD dwType ) const
{
	ADDTOCALLSTACK("CPointBase::GetRegion");
	// What region in the current CSector am i in ?
	// We only need to update this every 8 or so steps ?
	// REGION_TYPE_AREA
	if ( ! IsValidPoint())
		return NULL;

	CSector *pSector = GetSector();
	if ( pSector )
		return pSector->GetRegion(*this, dwType);

	return NULL;
}
Exemple #18
0
void CRegionBase::UnRealizeRegion()
{
	ADDTOCALLSTACK("CRegionBase::UnRealizeRegion");
	// remove myself from the world.
	// used in the case of a ship where the region will move.

	for ( int i=0; ; i++ )
	{
		CSector * pSector = GetSector(i);
		if ( pSector == NULL )
			break;
		// Does the rect overlap ?
		if ( ! IsOverlapped( pSector->GetRect()))
			continue;
		if ( pSector->UnLinkRegion( this ))
			m_iLinkedSectors--;
	}

}
Exemple #19
0
bool CRegionBase::SendSectorsVerb( LPCTSTR pszVerb, LPCTSTR pszArgs, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CRegionBase::SendSectorsVerb");
	// Send a command to all the CSectors in this region.

	bool fRet = false;
	for ( int i=0; ; i++ )
	{
		CSector * pSector = GetSector(i);
		if ( pSector == NULL )
			break;
		// Does the rect overlap ?
		if ( IsOverlapped( pSector->GetRect() ) )
		{
			CScript script( pszVerb, pszArgs );
			fRet |= pSector->r_Verb( script, pSrc );
		}
	}
	return( fRet );
}
Exemple #20
0
/// Funktion erteilt einen Kolonisierungsbefehl, sofern dies auch möglich ist.
/// @param pShip Zeiger des Schiffes
/// @return <code>true</code> wenn ein Kolonisierungsbefehl gegeben werden könnte
bool CShipAI::DoColonize(CShips* pShip)
{
	if (!pShip)
	{
		ASSERT(pShip);
		return false;
	}

	// Kolonieschiffe eine Kolonisierung vorschlagen
	if (pShip->GetShipType() != SHIP_TYPE::COLONYSHIP)
		return false;

	CSector* pSector = &m_pDoc->GetSector(pShip->GetKO().x, pShip->GetKO().y);
	// Gehört der Sektor aktuell auch keiner Minorrace (also niemanden oder uns selbst)
	if (pSector->GetOwnerOfSector() != "" && pSector->GetOwnerOfSector() != pShip->GetOwnerOfShip())
		return false;

	// Kolonisierungsbefehl geben
	for (int i = 0; i < pSector->GetNumberOfPlanets(); i++)
	{
		if (pSector->GetPlanet(i)->GetTerraformed() && !pSector->GetPlanet(i)->GetColonized())
		{
			// Hier muss als erstes ein möglicher neuer Kurs gelöscht werden
			pShip->SetTargetKO(CPoint(-1, -1));
			pShip->SetCurrentOrder(SHIP_ORDER::COLONIZE);
			return true;
		}
	}

	return false;
}
Exemple #21
0
void CRender::Load3DFluid()
{
	//if (strstr(Core.Params,"-no_volumetric_fog"))
	if (!RImplementation.o.volumetricfog)
		return;

	string_path fn_game;
	if ( FS.exist( fn_game, "$level$", "level.fog_vol" ) )
	{
		IReader *F	= FS.r_open( fn_game );
		u16 version	= F->r_u16();

		if(version == 3)
		{
			u32 cnt = F->r_u32();
			for(u32 i=0; i<cnt; ++i)
			{
				dx103DFluidVolume *pVolume = xr_new<dx103DFluidVolume>();
				pVolume->Load("", F, 0);

				//	Attach to sector's static geometry
				CSector *pSector = (CSector*)detectSector(pVolume->getVisData().sphere.P);
				//	3DFluid volume must be in render sector
				VERIFY(pSector);

				dxRender_Visual* pRoot = pSector->root();
				//	Sector must have root
				VERIFY(pRoot);
				VERIFY(pRoot->getType() == MT_HIERRARHY);
				
				((FHierrarhyVisual*)pRoot)->children.push_back(pVolume);
			}
		}

		FS.r_close(F);
	}
}
Exemple #22
0
void CFat32Device::CachePage(unsigned long page, unsigned char *buffer)
{
  DWORD time = timeGetTime();
  if (m_cache.size() >= CACHE_SIZE)
  { // remove the last used cache
    FATCACHE::iterator lastUsed = m_cache.begin();
    //CStdString usage;
    unsigned long smallest = 0;
    for (FATCACHE::iterator it = m_cache.begin(); it != m_cache.end(); ++it)
    {
      if ((*it).second->Usage(time) > (*lastUsed).second->Usage(time))
        lastUsed = it;
      if ((*it).second->Usage(time) < smallest)
        smallest = (*it).second->Usage(time);
/*      CStdString log;
      if ((*it).second->Usage(time) > 0xFF)
        log = "FF ";
      else
        log.Format("%02x ", (*it).second->Usage());
      usage += log;*/
    }
    //CLog::Log(LOGDEBUG, "%s", usage.c_str());
    // lastUsed is the one we remove
    unsigned long oldpage = (*lastUsed).first;
    CSector *sector = (*lastUsed).second;
    m_cache.erase(lastUsed);
//    CLog::Log(LOGDEBUG, "Swapping page %i for page %i, oldest usage: %d (%d)", oldpage, page, sector->Usage(time), smallest);
#ifdef FAT32_ALLOW_WRITING
    // write it out to disk if dirty
    if (sector->IsDirty())
      WritePage(oldpage, sector->Get());
#endif
    delete sector;
  }
  // cache our page
  m_cache.insert(pair<unsigned int, CSector *>(page, new CSector(buffer, time)));
}
Exemple #23
0
void CNgcScene::plat_post_load()
{
	// Now turn the temporary mesh lists into mesh arrays.
	mp_sector_table->IterateStart();
	CSector* pSector = mp_sector_table->IterateNext();
	while( pSector )
	{
		CNgcGeom *p_Ngc_geom = static_cast<CNgcGeom*>(pSector->GetGeom());

		p_Ngc_geom->CreateMeshArray();

		// First time through we just want to count the meshes,
		p_Ngc_geom->RegisterMeshArray( true );

		pSector = mp_sector_table->IterateNext();
	}

	// Now we have counted all the meshes, tell the engine to create the arrays to hold them.
	GetEngineScene()->CreateMeshArrays();
	
	// Now go through and actually add the meshes.
	mp_sector_table->IterateStart();
	pSector = mp_sector_table->IterateNext();
	while( pSector )
	{
		// Access platform dependent data.
		CNgcGeom *p_Ngc_geom = static_cast<CNgcGeom*>(pSector->GetGeom());

		p_Ngc_geom->RegisterMeshArray( false );

		pSector = mp_sector_table->IterateNext();
	}

	// Now all meshes are registered, tell the engine to sort them.
	GetEngineScene()->SortMeshes();
}
Exemple #24
0
void CRender::render_main	(Fmatrix&	m_ViewProjection, bool _fportals)
{
//	Msg						("---begin");
	marker					++;

	// Calculate sector(s) and their objects
	if (pLastSector)		{
		//!!!
		//!!! BECAUSE OF PARALLEL HOM RENDERING TRY TO DELAY ACCESS TO HOM AS MUCH AS POSSIBLE
		//!!!
		{
			// Traverse object database
			g_SpatialSpace->q_frustum
				(
				lstRenderables,
				ISpatial_DB::O_ORDERED,
				STYPE_RENDERABLE + STYPE_LIGHTSOURCE,
				ViewBase
				);

			// (almost) Exact sorting order (front-to-back)
			std::sort			(lstRenderables.begin(),lstRenderables.end(),pred_sp_sort);

			// Determine visibility for dynamic part of scene
			set_Object							(0);
			u32 uID_LTRACK						= 0xffffffff;
			if (phase==PHASE_NORMAL)			{
				uLastLTRACK	++;
				if (lstRenderables.size())		uID_LTRACK	= uLastLTRACK%lstRenderables.size();

				// update light-vis for current entity / actor
				CObject*	O					= g_pGameLevel->CurrentViewEntity();
				if (O)		{
					CROS_impl*	R					= (CROS_impl*) O->ROS();
					if (R)		R->update			(O);
				}

				// update light-vis for selected entity
				// track lighting environment
				if (lstRenderables.size())		{
					IRenderable*	renderable		= lstRenderables[uID_LTRACK]->dcast_Renderable	();
					if (renderable)	{
						CROS_impl*		T = (CROS_impl*)renderable->renderable_ROS	();
						if (T)			T->update	(renderable);
					}
				}
			}
		}

		// Traverse sector/portal structure
		PortalTraverser.traverse	
			(
			pLastSector,
			ViewBase,
			Device.vCameraPosition,
			m_ViewProjection,
			CPortalTraverser::VQ_HOM + CPortalTraverser::VQ_SSA + CPortalTraverser::VQ_FADE
			//. disabled scissoring (HW.Caps.bScissor?CPortalTraverser::VQ_SCISSOR:0)	// generate scissoring info
			);

		// Determine visibility for static geometry hierrarhy
		for (u32 s_it=0; s_it<PortalTraverser.r_sectors.size(); s_it++)
		{
			CSector*	sector		= (CSector*)PortalTraverser.r_sectors[s_it];
			IRender_Visual*	root	= sector->root();
			for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)	{
				set_Frustum			(&(sector->r_frustums[v_it]));
				add_Geometry		(root);
			}
		}

		// Traverse frustums
		for (u32 o_it=0; o_it<lstRenderables.size(); o_it++)
		{
			ISpatial*	spatial		= lstRenderables[o_it];		spatial->spatial_updatesector	();
			CSector*	sector		= (CSector*)spatial->spatial.sector;
			if	(0==sector)										continue;	// disassociated from S/P structure

			if (spatial->spatial.type & STYPE_LIGHTSOURCE)		{
				// lightsource
				light*			L				= (light*)	(spatial->dcast_Light());
				VERIFY							(L);
				float	lod		= L->get_LOD	();
				if (lod>EPS_L)	{
					vis_data&		vis		= L->get_homdata	( );
					if	(HOM.visible(vis))	Lights.add_light	(L);
				}
				continue					;
			}

			if	(PortalTraverser.i_marker != sector->r_marker)	continue;	// inactive (untouched) sector
			for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)	{
				CFrustum&	view	= sector->r_frustums[v_it];
				if (!view.testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R))	continue;

				if (spatial->spatial.type & STYPE_RENDERABLE)
				{
					// renderable
					IRenderable*	renderable		= spatial->dcast_Renderable	();
					VERIFY							(renderable);

					// Occlusion
					vis_data&		v_orig			= renderable->renderable.visual->vis;
					vis_data		v_copy			= v_orig;
					v_copy.box.xform				(renderable->renderable.xform);
					BOOL			bVisible		= HOM.visible(v_copy);
					v_orig.marker					= v_copy.marker;
					v_orig.accept_frame				= v_copy.accept_frame;
					v_orig.hom_frame				= v_copy.hom_frame;
					v_orig.hom_tested				= v_copy.hom_tested;
					if (!bVisible)					break;	// exit loop on frustums

					// Rendering
					set_Object						(renderable);
					renderable->renderable_Render	();
					set_Object						(0);
				}
				break;	// exit loop on frustums
			}
		}
		if (g_pGameLevel && (phase==PHASE_NORMAL))	g_pGameLevel->pHUD->Render_Last();		// HUD
	}
	else
	{
		set_Object									(0);
		if (g_pGameLevel && (phase==PHASE_NORMAL))	g_pGameLevel->pHUD->Render_Last();		// HUD
	}
}
Exemple #25
0
void CRandomEventCtrl::CalcShipEvents() const
{
	if (!IsActivated())
		return;

	CBotEDoc* pDoc = resources::pDoc;
	AssertBotE(pDoc);

	// Hüllenvirus
	for (int x = 0; x < STARMAP_SECTORS_HCOUNT; x++)
	{
		for (int y = 0; y < STARMAP_SECTORS_VCOUNT; y++)
		{
			// 0.1% Wahrscheinlichkeit für einen Hüllenvirus pro Sektor
			if (rand()%1000 != 0)
				continue;

			// gibt es keine Schiffe im Sektor, dann macht ein Hüllenvirus auch nichts
			CSector* pSector = &(pDoc->GetSystem(x, y));
			if (!pSector->GetIsShipInSector())
				continue;

			// allen Schiffe im Sektor die Hülle auf 1 reduzieren (außer Aliens)
			for (CShipMap::iterator i = pDoc->m_ShipMap.begin(); i != pDoc->m_ShipMap.end(); ++i)
			{
				if (i->second->IsAlien())
					continue;

				if (i->second->GetCo() != pSector->GetCo())
					continue;

				int nCurrentHull = i->second->GetHull()->GetCurrentHull();
				i->second->GetHull()->SetCurrentHull(-(nCurrentHull - 1), true);

				// allen Schiffen in der Flotte ebenfalls die Hülle auf 1 setzen
				for (CShips::iterator j = i->second->begin(); j != i->second->end(); ++j)
				{
					nCurrentHull = j->second->GetHull()->GetCurrentHull();
					j->second->GetHull()->SetCurrentHull(-(nCurrentHull - 1), true);
				}
			}

			// Nachrichten an alle Major welche Schiffe in diesem Sektor hatten
			const std::map<CString, CMajor*>* pmMajors = pDoc->GetRaceCtrl()->GetMajors();
			for (map<CString, CMajor*>::const_iterator it = pmMajors->begin(); it != pmMajors->end(); ++it)
			{
				if (!pSector->GetOwnerOfShip(it->first, true))
					continue;

				CMajor* pMajor = it->second;
				if (!pMajor)
					continue;

				const CString& sSectorName = pSector->CoordsName(true);

				CString sMessageText = CLoc::GetString("EVENTHULLVIRUS", false, sSectorName);
				CEmpireNews message;
				message.CreateNews(sMessageText,EMPIRE_NEWS_TYPE::MILITARY,pSector->GetName(),pSector->GetCo());
				pMajor->GetEmpire()->AddMsg(message);

				if (pMajor->IsHumanPlayer())
				{
					resources::pClientWorker->SetToEmpireViewFor(*pMajor);
					pMajor->GetEmpire()->PushEvent(boost::make_shared<CEventRandom>(pMajor->GetRaceID(), "HullVirus", sMessageText, ""));
				}
			}
		}
	}
}
Exemple #26
0
void CSector::traverse			(CFrustum &F, _scissor& R_scissor)
{
	// Register traversal process
	if (r_marker	!=	PortalTraverser.i_marker)	{
		r_marker							=	PortalTraverser.i_marker;
		PortalTraverser.r_sectors.push_back	(this);
		r_frustums.clear					();
		r_scissors.clear					();
	}
	r_frustums.push_back		(F);
	r_scissors.push_back		(R_scissor);

	// Search visible portals and go through them
	sPoly	S,D;
	for	(u32 I=0; I<m_portals.size(); I++)
	{
		if (m_portals[I]->marker == PortalTraverser.i_marker) continue;

		CPortal* PORTAL = m_portals[I];
		CSector* pSector;

		// Select sector (allow intersecting portals to be finely classified)
		if (PORTAL->bDualRender) {
			pSector = PORTAL->getSector						(this);
		} else {
			pSector = PORTAL->getSectorBack					(PortalTraverser.i_vBase);
			if (pSector==this)								continue;
			if (pSector==PortalTraverser.i_start)			continue;
		}

		// Early-out sphere
		if (!F.testSphere_dirty(PORTAL->S.P,PORTAL->S.R))	continue;

		// SSA	(if required)
		if (PortalTraverser.i_options&CPortalTraverser::VQ_SSA)
		{
			Fvector				dir2portal;
			dir2portal.sub		(PORTAL->S.P,	PortalTraverser.i_vBase);
			float R				=	PORTAL->S.R	;
			float distSQ		=	dir2portal.square_magnitude();
			float ssa			=	R*R/distSQ;
			dir2portal.div		(_sqrt(distSQ));
			ssa					*=	_abs(PORTAL->P.n.dotproduct(dir2portal));
			if (ssa<r_ssaDISCARD)	continue;

			if (PortalTraverser.i_options&CPortalTraverser::VQ_FADE)	{
				if (ssa<r_ssaLOD_A)	PortalTraverser.fade_portal			(PORTAL,ssa);
				if (ssa<r_ssaLOD_B)	continue							;
			}
		}

		// Clip by frustum
		svector<Fvector,8>&	POLY = PORTAL->getPoly();
		S.assign			(&*POLY.begin(),POLY.size()); D.clear();
		sPoly* P			= F.ClipPoly(S,D);
		if (0==P)			continue;

		// Scissor and optimized HOM-testing
		_scissor			scissor	;
		if (PortalTraverser.i_options&CPortalTraverser::VQ_SCISSOR && (!PORTAL->bDualRender))
		{
			// Build scissor rectangle in projection-space
			Fbox2	bb;	bb.invalidate(); float depth = flt_max;
			sPoly&	p	= *P;
			for		(u32 vit=0; vit<p.size(); vit++)	{
				Fvector4	t;	
				Fmatrix&	M	= PortalTraverser.i_mXFORM_01;
				Fvector&	v	= p[vit];

				t.x = v.x*M._11 + v.y*M._21 + v.z*M._31 + M._41;
				t.y = v.x*M._12 + v.y*M._22 + v.z*M._32 + M._42;
				t.z = v.x*M._13 + v.y*M._23 + v.z*M._33 + M._43;
				t.w = v.x*M._14 + v.y*M._24 + v.z*M._34 + M._44;
				t.mul	(1.f/t.w);

				if (t.x < bb.min.x)	bb.min.x	= t.x; 
				if (t.x > bb.max.x) bb.max.x	= t.x;
				if (t.y < bb.min.y)	bb.min.y	= t.y; 
				if (t.y > bb.max.y) bb.max.y	= t.y;
				if (t.z < depth)	depth		= t.z;
			}
			// Msg	("bb(%s): (%f,%f)-(%f,%f), d=%f", PORTAL->bDualRender?"true":"false",bb.min.x, bb.min.y, bb.max.x, bb.max.y,depth);
			if (depth<EPS)	{
				scissor	= R_scissor;

				// Cull by HOM (slower algo)
				if  (
					(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
					(!RImplementation.HOM.visible(*P))
					)	continue;
			} else {
				// perform intersection (this is just to be sure, it is probably clipped in 3D already)
				if (bb.min.x > R_scissor.min.x)	scissor.min.x = bb.min.x; else scissor.min.x = R_scissor.min.x;
				if (bb.min.y > R_scissor.min.y)	scissor.min.y = bb.min.y; else scissor.min.y = R_scissor.min.y;
				if (bb.max.x < R_scissor.max.x) scissor.max.x = bb.max.x; else scissor.max.x = R_scissor.max.x;
				if (bb.max.y < R_scissor.max.y) scissor.max.y = bb.max.y; else scissor.max.y = R_scissor.max.y;
				scissor.depth	= depth;

				// Msg	("scissor: (%f,%f)-(%f,%f)", scissor.min.x, scissor.min.y, scissor.max.x, scissor.max.y);
				// Check if box is non-empty
				if (scissor.min.x >= scissor.max.x)	continue;
				if (scissor.min.y >= scissor.max.y)	continue;

				// Cull by HOM (faster algo)
				if  (
					(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
					(!RImplementation.HOM.visible(scissor,depth))
					)	continue;
			}
		} else {
			scissor	= R_scissor;

			// Cull by HOM (slower algo)
			if  (
				(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
				(!RImplementation.HOM.visible(*P))
				)	continue;
		}

		// Create _new_ frustum and recurse
		CFrustum				Clip;
		Clip.CreateFromPortal	(P, PORTAL->P.n, PortalTraverser.i_vBase,PortalTraverser.i_mXFORM);
		PORTAL->marker			= PortalTraverser.i_marker;
		PORTAL->bDualRender		= FALSE;
		pSector->traverse		(Clip,scissor);
	}
}
Exemple #27
0
bool CPointBase::r_WriteVal( LPCTSTR pszKey, CGString & sVal ) const
{
	ADDTOCALLSTACK("CPointBase::r_WriteVal");
	if ( !strnicmp( pszKey, "STATICS", 7 ) )
	{
		pszKey	+= 7;
		const CGrayMapBlock * pBlock = g_World.GetMapBlock( *(this) );
		if ( !pBlock ) return false;

		if ( *pszKey == '\0' )
		{
			int iStaticQty = 0;
			for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); i++ )
			{
				const CUOStaticItemRec * pStatic = pBlock->m_Statics.GetStatic( i );
				CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map );
				if ( this->GetDist( ptTest ) > 0 )
					continue;
				iStaticQty++;
			}

			sVal.FormatVal( iStaticQty );
			return true;
		}

		SKIP_SEPARATORS( pszKey );

		const CUOStaticItemRec * pStatic = NULL;
		int iStatic = 0;
		int type = 0;
		
		if ( !strnicmp( pszKey, "FINDID", 6 ) )
		{
			pszKey += 6;
			SKIP_SEPARATORS( pszKey );
			iStatic = Exp_GetVal( pszKey );
			type = RES_GET_TYPE( iStatic );
			if ( type == 0 )
				type = RES_ITEMDEF;
			SKIP_SEPARATORS( pszKey );
		}
		else
		{
			iStatic = Exp_GetVal( pszKey );
			type = RES_GET_TYPE( iStatic );
		}
		
		if ( type == RES_ITEMDEF )
		{
			const CItemBase * pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iStatic)));
			if ( !pItemDef )
			{
				sVal.FormatVal( 0 );
				return false;
			}
			for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); pStatic = NULL, i++ )
			{
				pStatic = pBlock->m_Statics.GetStatic( i );
				CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map);
				if ( this->GetDist( ptTest ) > 0 )
					continue;
				if ( pStatic->GetDispID() == pItemDef->GetDispID() )
					break;
			}
		}
		else
		{
			for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); pStatic = NULL, i++ )
			{
				pStatic = pBlock->m_Statics.GetStatic( i );
				CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map);
				if ( this->GetDist( ptTest ) > 0 )
					continue;
				if ( iStatic == 0 )
					break;
				iStatic--;
			}
		}

		if ( !pStatic )
		{
			sVal.FormatHex(0);
			return true;
		}

		SKIP_SEPARATORS( pszKey );
		if ( !*pszKey )
			pszKey	= "ID";

		ITEMID_TYPE idTile = pStatic->GetDispID();

		if ( !strnicmp( pszKey, "COLOR", 5 ) )
		{
			sVal.FormatHex( pStatic->m_wHue );
			return true;
		}
		else if ( !strnicmp( pszKey, "ID", 2 ) )
		{
			sVal.FormatHex( idTile );
			return true;
		}
		else if ( !strnicmp( pszKey, "Z", 1 ) )
		{
			sVal.FormatVal( pStatic->m_z );
			return true;
		}

		// Check the script def for the item.
		CItemBase * pItemDef = CItemBase::FindItemBase( idTile );
		if ( pItemDef == NULL )
		{
			DEBUG_ERR(("Must have ITEMDEF section for item ID 0%x\n", idTile ));
			return false;
		}

		return pItemDef->r_WriteVal( pszKey, sVal, &g_Serv );
	}
	else if ( !strnicmp( pszKey, "COMPONENTS", 10) )
	{
		pszKey += 10;
		
		CRegionLinks rlinks;
		const CRegionBase* pRegion = NULL;
		CItem* pItem = NULL;
		const CGrayMulti* pMulti = NULL;
		const CUOMultiItemRec2* pMultiItem = NULL;
		size_t iMultiQty = GetRegions(REGION_TYPE_MULTI, rlinks);

		if ( *pszKey == '\0' )
		{
			int iComponentQty = 0;
			for (size_t i = 0; i < iMultiQty; i++)
			{
				pRegion = rlinks.GetAt(i);
				if (pRegion == NULL)
					continue;

				pItem = pRegion->GetResourceID().ItemFind();
				if (pItem == NULL)
					continue;

				const CPointMap ptMulti = pItem->GetTopPoint();
				pMulti = g_Cfg.GetMultiItemDefs(pItem);
				if (pMulti == NULL)
					continue;

				size_t iQty = pMulti->GetItemCount();
				for (size_t ii = 0; ii < iQty; ii++)
				{
					pMultiItem = pMulti->GetItem(ii);
					if (pMultiItem == NULL)
						break;
					if (pMultiItem->m_visible == 0)
						continue;

					CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map);
					if (GetDist(ptTest) > 0)
						continue;

					iComponentQty++;
				}
			}

			sVal.FormatVal( iComponentQty );
			return true;
		}

		SKIP_SEPARATORS( pszKey );

		int iComponent = 0;
		int type = 0;
		
		if ( strnicmp( pszKey, "FINDID", 6 ) == 0 )
		{
			pszKey += 6;
			SKIP_SEPARATORS( pszKey );
			iComponent = Exp_GetVal( pszKey );
			type = RES_GET_TYPE( iComponent );
			if ( type == 0 )
				type = RES_ITEMDEF;
			SKIP_SEPARATORS( pszKey );
		}
		else
		{
			iComponent = Exp_GetVal( pszKey );
			type = RES_GET_TYPE( iComponent );
		}
		
		if ( type == RES_ITEMDEF )
		{
			const CItemBase * pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iComponent)));
			if ( pItemDef == NULL )
			{
				sVal.FormatVal( 0 );
				return false;
			}
			
			for (size_t i = 0; i < iMultiQty; i++)
			{
				pRegion = rlinks.GetAt(i);
				if (pRegion == NULL)
					continue;

				pItem = pRegion->GetResourceID().ItemFind();
				if (pItem == NULL)
					continue;

				const CPointMap ptMulti = pItem->GetTopPoint();
				pMulti = g_Cfg.GetMultiItemDefs(pItem);
				if (pMulti == NULL)
					continue;

				size_t iQty = pMulti->GetItemCount();
				for (size_t ii = 0; ii < iQty; pMultiItem = NULL, ii++)
				{
					pMultiItem = pMulti->GetItem(ii);
					if (pMultiItem == NULL)
						break;
					if (pMultiItem->m_visible == 0)
						continue;
					CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map);
					if (GetDist(ptTest) > 0)
						continue;

					const CItemBase* pMultiItemDef = CItemBase::FindItemBase(pMultiItem->GetDispID());
					if (pMultiItemDef != NULL && pMultiItemDef->GetDispID() == pItemDef->GetDispID())
						break;
				}

				if (pMultiItem != NULL)
					break;
			}
		}
		else
		{
			for (size_t i = 0; i < iMultiQty; i++)
			{
				pRegion = rlinks.GetAt(i);
				if (pRegion == NULL)
					continue;

				pItem = pRegion->GetResourceID().ItemFind();
				if (pItem == NULL)
					continue;

				const CPointMap ptMulti = pItem->GetTopPoint();
				pMulti = g_Cfg.GetMultiItemDefs(pItem);
				if (pMulti == NULL)
					continue;

				size_t iQty = pMulti->GetItemCount();
				for (size_t ii = 0; ii < iQty; pMultiItem = NULL, ii++)
				{
					pMultiItem = pMulti->GetItem(ii);
					if (pMultiItem == NULL)
						break;
					if (pMultiItem->m_visible == 0)
						continue;
					CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map);
					if (GetDist(ptTest) > 0)
						continue;

					if (iComponent == 0)
						break;

					iComponent--;
				}

				if (pMultiItem != NULL)
					break;
			}
		}

		if ( pMultiItem == NULL )
		{
			sVal.FormatHex(0);
			return true;
		}

		SKIP_SEPARATORS( pszKey );
		if ( !*pszKey )
			pszKey	= "ID";

		ITEMID_TYPE idTile = pMultiItem->GetDispID();

		if ( strnicmp( pszKey, "ID", 2 ) == 0 )
		{
			sVal.FormatHex( idTile );
			return true;
		}
		else if ( strnicmp( pszKey, "MULTI", 5 ) == 0 )
		{
			pszKey += 5;
			if (*pszKey != '\0')
			{
				SKIP_SEPARATORS(pszKey);
				return pItem->r_WriteVal( pszKey, sVal, &g_Serv );
			}

			sVal.FormatHex( pItem->GetUID() );
			return true;
		}
		else if ( strnicmp( pszKey, "Z", 1 ) == 0 )
		{
			sVal.FormatVal( pItem->GetTopZ() + pMultiItem->m_dz );
			return true;
		}

		// Check the script def for the item.
		CItemBase * pItemDef = CItemBase::FindItemBase( idTile );
		if ( pItemDef == NULL )
		{
			DEBUG_ERR(("Must have ITEMDEF section for item ID 0%x\n", idTile ));
			return false;
		}

		return pItemDef->r_WriteVal( pszKey, sVal, &g_Serv );
	}
	
	int index = FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys)-1 );
	if ( index < 0 )
		return false;

	switch ( index )
	{
		case PT_M:
		case PT_MAP:
			sVal.FormatVal(m_map);
			break;
		case PT_X:
			sVal.FormatVal(m_x);
			break;
		case PT_Y:
			sVal.FormatVal(m_y);
			break;
		case PT_Z:
			sVal.FormatVal(m_z);
			break;
		case PT_ISNEARTYPE:
		{
			pszKey += 10;
			SKIP_SEPARATORS( pszKey );
			SKIP_ARGSEP( pszKey );

			int iType = g_Cfg.ResourceGetIndexType( RES_TYPEDEF, pszKey );
			int iDistance = 0;
			bool bCheckMulti = false;

			SKIP_IDENTIFIERSTRING( pszKey );
			SKIP_SEPARATORS( pszKey );
			SKIP_ARGSEP( pszKey );

			if ( *pszKey ) iDistance = Exp_GetVal(pszKey);
			if ( *pszKey ) bCheckMulti = Exp_GetVal(pszKey) != 0;
			sVal.FormatVal( g_World.IsItemTypeNear(*this, static_cast<IT_TYPE>(iType), iDistance, bCheckMulti));
			break;
		}
		case PT_REGION:
		{
			// Check that the syntax is correct.
			if ( pszKey[6] && pszKey[6] != '.' )
				return false;

			CRegionWorld * pRegionTemp = dynamic_cast <CRegionWorld*>(this->GetRegion(REGION_TYPE_AREA | REGION_TYPE_MULTI));

			if ( !pszKey[6] )
			{
				// We're just checking if the reference is valid.
				sVal.FormatVal( pRegionTemp? 1:0 );
				return true;
			}
			
			// We're trying to retrieve a property from the region.
			pszKey += 7;
			if ( pRegionTemp )
				return pRegionTemp->r_WriteVal( pszKey, sVal, &g_Serv );

			return false;
		}
		case PT_ROOM:
		{
			if ( pszKey[4] && pszKey[4] != '.' )
				return false;

			CRegionBase * pRegionTemp = this->GetRegion( REGION_TYPE_ROOM );

			if ( !pszKey[4] )
			{
				sVal.FormatVal( pRegionTemp? 1:0 );
				return true;
			}

			pszKey += 5;
			if ( pRegionTemp )
				return pRegionTemp->r_WriteVal( pszKey, sVal, &g_Serv );

			return false;
		}
		case PT_SECTOR:
		{
			if ( pszKey[6] == '.' )
			{
				pszKey += 7;
				CSector * pSectorTemp = this->GetSector();
				if (pSectorTemp)
					return pSectorTemp->r_WriteVal(pszKey, sVal, &g_Serv);
			}
			return false;
		}
		default:
		{
			const CUOMapMeter * pMeter = g_World.GetMapMeter(*this);
			if ( pMeter )
			{
				switch( index )
				{
					case PT_TYPE:
						{
							CItemTypeDef * pTypeDef = g_World.GetTerrainItemTypeDef( pMeter->m_wTerrainIndex );
							if ( pTypeDef != NULL )
								sVal = pTypeDef->GetResourceName();
							else
								sVal = "";
						} return true;	
					case PT_TERRAIN:
						{
							pszKey += strlen(sm_szLoadKeys[index]);
							if ( *pszKey == '.' )	// do we have an argument?
							{
								SKIP_SEPARATORS( pszKey );
								if ( !strnicmp( pszKey, "Z", 1 ))
								{
									sVal.FormatVal( pMeter->m_z );
									return( true );
								}
								
								return( false );
							}
							else
							{
								sVal.FormatHex( pMeter->m_wTerrainIndex );
							}
						} return true;
				}
			}
			return false;
		}
	}

	return true;
}
Exemple #28
0
void CRender::Calculate				()
{
	#ifdef _GPA_ENABLED	
		TAL_SCOPED_TASK_NAMED( "CRender::Calculate()" );
	#endif // _GPA_ENABLED

	Device.Statistic->RenderCALC.Begin();

	// Transfer to global space to avoid deep pointer access
	IRender_Target* T				=	getTarget	();
	float	fov_factor				=	_sqr		(90.f / Device.fFOV);
	g_fSCREEN						=	float(T->get_width()*T->get_height())*fov_factor*(EPS_S+ps_r__LOD);
	r_ssaDISCARD					=	_sqr(ps_r__ssaDISCARD)		/g_fSCREEN;
	r_ssaDONTSORT					=	_sqr(ps_r__ssaDONTSORT/3)	/g_fSCREEN;
	r_ssaLOD_A						=	_sqr(ps_r1_ssaLOD_A/3)		/g_fSCREEN;
	r_ssaLOD_B						=	_sqr(ps_r1_ssaLOD_B/3)		/g_fSCREEN;
	r_ssaGLOD_start					=	_sqr(ps_r__GLOD_ssa_start/3)/g_fSCREEN;
	r_ssaGLOD_end					=	_sqr(ps_r__GLOD_ssa_end/3)	/g_fSCREEN;
	r_ssaHZBvsTEX					=	_sqr(ps_r__ssaHZBvsTEX/3)	/g_fSCREEN;

	// Frustum & HOM rendering
	ViewBase.CreateFromMatrix		(Device.mFullTransform,FRUSTUM_P_LRTB|FRUSTUM_P_FAR);
	View							= 0;
	HOM.Enable						();
	HOM.Render						(ViewBase);
	gm_SetNearer					(FALSE);
	phase							= PHASE_NORMAL;

	// Detect camera-sector
	if (!vLastCameraPos.similar(Device.vCameraPosition,EPS_S)) 
	{
		CSector* pSector		= (CSector*)detectSector(Device.vCameraPosition);
		if (pSector && (pSector!=pLastSector))
			g_pGamePersistent->OnSectorChanged( translateSector(pSector) );

		if (0==pSector) pSector = pLastSector;
		pLastSector = pSector;
		vLastCameraPos.set(Device.vCameraPosition);
	}

	// Check if camera is too near to some portal - if so force DualRender
	if (rmPortals) 
	{
		Fvector box_radius;		box_radius.set(EPS_L*2,EPS_L*2,EPS_L*2);
		Sectors_xrc.box_options	(CDB::OPT_FULL_TEST);
		Sectors_xrc.box_query	(rmPortals,Device.vCameraPosition,box_radius);
		for (int K=0; K<Sectors_xrc.r_count(); K++)
		{
			CPortal*	pPortal		= (CPortal*) Portals[rmPortals->get_tris()[Sectors_xrc.r_begin()[K].id].dummy];
			pPortal->bDualRender	= TRUE;
		}
	}
	//
	if (L_DB)
		L_DB->Update();

	// Main process
	marker	++;
	if (pLastSector)
	{
		// Traverse sector/portal structure
		PortalTraverser.traverse	
			(
			pLastSector,
			ViewBase,
			Device.vCameraPosition,
			Device.mFullTransform,
			CPortalTraverser::VQ_HOM + CPortalTraverser::VQ_SSA + CPortalTraverser::VQ_FADE
			);

		// Determine visibility for static geometry hierrarhy
		if  (psDeviceFlags.test(rsDrawStatic))	{
			for (u32 s_it=0; s_it<PortalTraverser.r_sectors.size(); s_it++)
			{
				CSector*	sector		= (CSector*)PortalTraverser.r_sectors[s_it];
				dxRender_Visual*	root	= sector->root();
				for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)
				{
					set_Frustum			(&(sector->r_frustums[v_it]));
					add_Geometry		(root);
				}
			}
		}

		// Traverse object database
		if  (psDeviceFlags.test(rsDrawDynamic))	{
			g_SpatialSpace->q_frustum
				(
				lstRenderables,
				ISpatial_DB::O_ORDERED,
				STYPE_RENDERABLE + STYPE_LIGHTSOURCE,
				ViewBase
				);

			// Exact sorting order (front-to-back)
			std::sort							(lstRenderables.begin(),lstRenderables.end(),pred_sp_sort);

			// Determine visibility for dynamic part of scene
			set_Object							(0);
			g_hud->Render_First					( );	// R1 shadows
			g_hud->Render_Last					( );	
			u32 uID_LTRACK						= 0xffffffff;
			if (phase==PHASE_NORMAL)			{
				uLastLTRACK	++;
				if (lstRenderables.size())		uID_LTRACK	= uLastLTRACK%lstRenderables.size();

				// update light-vis for current entity / actor
				CObject*	O					= g_pGameLevel->CurrentViewEntity();
				if (O)		{
					CROS_impl*	R					= (CROS_impl*) O->ROS();
					if (R)		R->update			(O);
				}
			}
			for (u32 o_it=0; o_it<lstRenderables.size(); o_it++)
			{
				ISpatial*	spatial		= lstRenderables[o_it];		spatial->spatial_updatesector	();
				CSector*	sector		= (CSector*)spatial->spatial.sector	;
				if	(0==sector)										
					continue;	// disassociated from S/P structure

				// Filter only not light spatial
				if	(PortalTraverser.i_marker != sector->r_marker && (spatial->spatial.type & STYPE_RENDERABLE) )	continue;	// inactive (untouched) sector

				if (spatial->spatial.type & STYPE_RENDERABLE)
				{
					for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)
					{
						set_Frustum			(&(sector->r_frustums[v_it]));

						if (!View->testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R) /*&& (spatial->spatial.type & STYPE_RENDERABLE)*/)	continue;
						// renderable
						IRenderable*	renderable		= spatial->dcast_Renderable	();
						if (0==renderable)	{
							// It may be an glow
							CGlow*		glow				= dynamic_cast<CGlow*>(spatial);
							VERIFY							(glow);
							L_Glows->add					(glow);
						} else {
							// Occlusiond
							vis_data&		v_orig			= renderable->renderable.visual->getVisData();
							vis_data		v_copy			= v_orig;
							v_copy.box.xform				(renderable->renderable.xform);
							BOOL			bVisible		= HOM.visible(v_copy);
							v_orig.accept_frame				= v_copy.accept_frame;
							v_orig.marker					= v_copy.marker;
							v_orig.hom_frame				= v_copy.hom_frame;
							v_orig.hom_tested				= v_copy.hom_tested;
							if (!bVisible)					break;	// exit loop on frustums

							// rendering
							if (o_it==uID_LTRACK && renderable->renderable_ROS())	{
								// track lighting environment
								CROS_impl*		T = (CROS_impl*)renderable->renderable_ROS();
								T->update			(renderable);
							}
							set_Object						(renderable);
							renderable->renderable_Render	();
							set_Object						(0);	//? is it needed at all
						}
						break;	// exit loop on frustums
					}
				} 
				else
				{
					if ( ViewBase.testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R) )
					{
						VERIFY								(spatial->spatial.type & STYPE_LIGHTSOURCE);
						// lightsource
						light*			L					= (light*)	spatial->dcast_Light	();
						VERIFY								(L);
						if (L->spatial.sector)				{
							vis_data&		vis		= L->get_homdata	( );
							if	(HOM.visible(vis))	L_DB->add_light		(L);
						}
					}
				}
			}
		}

		// Calculate miscelaneous stuff
		L_Shadows->calculate								();
		L_Projector->calculate								();
	}
	else
	{
		set_Object											(0);
		/*
		g_pGameLevel->pHUD->Render_First					();	
		g_pGameLevel->pHUD->Render_Last						();	

		// Calculate miscelaneous stuff
		L_Shadows->calculate								();
		L_Projector->calculate								();
		*/
	}

	// End calc
	Device.Statistic->RenderCALC.End	();
}
void	R_dsgraph_structure::r_dsgraph_render_R1_box	(IRender_Sector* _S, Fbox& BB, int sh)
{
	CSector*	S			= (CSector*)_S;
	lstVisuals.clear		();
	lstVisuals.push_back	(S->root());
	
	for (u32 test=0; test<lstVisuals.size(); test++)
	{
		IRender_Visual*	V		= 	lstVisuals[test];
		
		// Visual is 100% visible - simply add it
		xr_vector<IRender_Visual*>::iterator I,E;	// it may be usefull for 'hierrarhy' visuals
		
		switch (V->Type) {
		case MT_HIERRARHY:
			{
				// Add all children
				FHierrarhyVisual* pV = (FHierrarhyVisual*)V;
				I = pV->children.begin	();
				E = pV->children.end		();
				for (; I!=E; I++)		{
					IRender_Visual* T			= *I;
					if (BB.intersect(T->vis.box))	lstVisuals.push_back(T);
				}
			}
			break;
		case MT_SKELETON_ANIM:
		case MT_SKELETON_RIGID:
			{
				// Add all children	(s)
				CKinematics * pV		= (CKinematics*)V;
				pV->CalculateBones		(TRUE);
				I = pV->children.begin	();
				E = pV->children.end		();
				for (; I!=E; I++)		{
					IRender_Visual* T				= *I;
					if (BB.intersect(T->vis.box))	lstVisuals.push_back(T);
				}
			}
			break;
		case MT_LOD:
			{
				FLOD		* pV		=	(FLOD*) V;
				I = pV->children.begin		();
				E = pV->children.end		();
				for (; I!=E; I++)		{
					IRender_Visual* T				= *I;
					if (BB.intersect(T->vis.box))	lstVisuals.push_back(T);
				}
			}
			break;
		default:
			{
				// Renderable visual
				ShaderElement* E	= V->shader->E[sh]._get();
				if (E) {
					for (u32 pass=0; pass<E->passes.size(); pass++)
					{
						RCache.set_Element			(E,pass);
						V->Render					(-1.f);
					}
				}
			}
			break;
		}
	}
}
// sub-space rendering - main procedure
void	R_dsgraph_structure::r_dsgraph_render_subspace	(IRender_Sector* _sector, CFrustum* _frustum, Fmatrix& mCombined, Fvector& _cop, BOOL _dynamic, BOOL _precise_portals)
{
	VERIFY							(_sector);
	RImplementation.marker			++;			// !!! critical here

	// Save and build new frustum, disable HOM
	CFrustum	ViewSave			= ViewBase;
	ViewBase						= *_frustum;
	View							= &ViewBase;

	if (_precise_portals && RImplementation.rmPortals)		{
		// Check if camera is too near to some portal - if so force DualRender
		Fvector box_radius;		box_radius.set	(EPS_L*20,EPS_L*20,EPS_L*20);
		RImplementation.Sectors_xrc.box_options	(CDB::OPT_FULL_TEST);
		RImplementation.Sectors_xrc.box_query	(RImplementation.rmPortals,_cop,box_radius);
		for (int K=0; K<RImplementation.Sectors_xrc.r_count(); K++)
		{
			CPortal*	pPortal		= (CPortal*) RImplementation.Portals[RImplementation.rmPortals->get_tris()[RImplementation.Sectors_xrc.r_begin()[K].id].dummy];
			pPortal->bDualRender	= TRUE;
		}
	}

	// Traverse sector/portal structure
	PortalTraverser.traverse		( _sector, ViewBase, _cop, mCombined, 0 );

	// Determine visibility for static geometry hierrarhy
	for (u32 s_it=0; s_it<PortalTraverser.r_sectors.size(); s_it++)
	{
		CSector*	sector		= (CSector*)PortalTraverser.r_sectors[s_it];
		IRender_Visual*	root	= sector->root();
		for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)	{
			set_Frustum			(&(sector->r_frustums[v_it]));
			add_Geometry		(root);
		}
	}

	if (_dynamic)
	{
		set_Object						(0);

		// Traverse object database
		g_SpatialSpace->q_frustum
			(
			lstRenderables,
			ISpatial_DB::O_ORDERED,
			STYPE_RENDERABLE,
			ViewBase
			);

		// Determine visibility for dynamic part of scene
		for (u32 o_it=0; o_it<lstRenderables.size(); o_it++)
		{
			ISpatial*	spatial		= lstRenderables[o_it];
			CSector*	sector		= (CSector*)spatial->spatial.sector;
			if	(0==sector)										continue;	// disassociated from S/P structure
			if	(PortalTraverser.i_marker != sector->r_marker)	continue;	// inactive (untouched) sector
			for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)
			{
				set_Frustum			(&(sector->r_frustums[v_it]));
				if (!View->testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R))	continue;

				// renderable
				IRenderable*	renderable		= spatial->dcast_Renderable	();
				if (0==renderable)				continue;					// unknown, but renderable object (r1_glow???)

				renderable->renderable_Render	();
			}
		}
	}

	// Restore
	ViewBase						= ViewSave;
	View							= 0;
}