示例#1
0
文件: qe3.cpp 项目: GSIO01/GtkRadiant
/*
   ===============
   ConnectEntities

   Sets target / targetname on the two entities selected
   from the first selected to the secon
   ===============
 */
void ConnectEntities( void ){
	entity_t    *e1, *e2;
	const char      *target;
	char        *newtarg = NULL;

	if ( g_qeglobals.d_select_count != 2 ) {
		Sys_Status( "Must have two brushes selected", 0 );
		Sys_Beep();
		return;
	}

	e1 = g_qeglobals.d_select_order[0]->owner;
	e2 = g_qeglobals.d_select_order[1]->owner;

	if ( e1 == world_entity || e2 == world_entity ) {
		Sys_Status( "Can't connect to the world", 0 );
		Sys_Beep();
		return;
	}

	if ( e1 == e2 ) {
		Sys_Status( "Brushes are from same entity", 0 );
		Sys_Beep();
		return;
	}

	target = ValueForKey( e1, "target" );
	if ( target && target[0] ) {
		newtarg = g_strdup( target );
	}
	else
	{
		target = ValueForKey( e2, "targetname" );
		if ( target && target[0] ) {
			newtarg = g_strdup( target );
		}
		else{
			Entity_Connect( e1, e2 );
		}
	}

	if ( newtarg != NULL ) {
		SetKeyValue( e1, "target", newtarg );
		SetKeyValue( e2, "targetname", newtarg );
		g_free( newtarg );
	}

	Sys_UpdateWindows( W_XY | W_CAMERA );

	Select_Deselect();
	Select_Brush( g_qeglobals.d_select_order[1] );
}
示例#2
0
/*!\todo Possibly make the import Undo-friendly by calling Undo_End for new brushes and ents */
void Map_ImportEntities( CPtrArray *ents, bool bAddSelected = false ){
	int num_ents, num_brushes;
	CPtrArray *brushes;
	vec3_t mins, maxs;
	entity_t *e;
	brush_t *b;
	face_t *f;
	int i,j;

	GPtrArray *new_ents = g_ptr_array_new();

	g_qeglobals.bPrimitBrushes = false;

	brush_t *pBrushList = ( bAddSelected ) ? &selected_brushes : &active_brushes;

	bool bDoneBPCheck = false;
	g_qeglobals.bNeedConvert = false;
	// HACK: find out if this map file was a BP one
	// check the first brush in the file that is NOT a patch
	// this will not be necessary when we allow both formats in the same file
	num_ents = ents->GetSize();
	for ( i = 0; !bDoneBPCheck && i < num_ents; i++ )
	{
		e = (entity_t*)ents->GetAt( i );
		brushes = (CPtrArray*)e->pData;
		num_brushes = brushes->GetSize();
		for ( j = 0; !bDoneBPCheck && j < num_brushes; j++ )
		{
			/*!todo Allow mixing texdef formats per-face. */
			b = (brush_t *)brushes->GetAt( j );
			if ( b->patchBrush ) {
				continue;
			}
			bDoneBPCheck = true;
			int BP_param = -1;
			if ( b->bBrushDef && !g_qeglobals.m_bBrushPrimitMode ) {
				BP_param = 0;
			}
			else if ( !b->bBrushDef && g_qeglobals.m_bBrushPrimitMode ) {
				BP_param = 1;
			}

			if ( BP_param != -1 ) {
				switch ( BP_MessageBox( BP_param ) )
				{
				case 0:
					Map_FreeEntities( ents );
					return;
				case 1:
					g_qeglobals.bNeedConvert = true;
					break;
				case 2:
					g_qeglobals.bNeedConvert = false;
					break;
				}
			}
		}
	}

	// process the entities into the world geometry
	num_ents = ents->GetSize();
	for ( i = 0; i < num_ents; i++ )
	{
		num_brushes = 0;
		e = (entity_t*)ents->GetAt( i );
		brushes = (CPtrArray*)e->pData;

		num_brushes = brushes->GetSize();
		// link brushes into entity
		for ( j = 0; j < num_brushes; j++ )
		{
			Entity_LinkBrush( e, (brush_t *)brushes->GetAt( j ) );
			g_qeglobals.d_parsed_brushes++;
		}
		brushes->RemoveAll();
		delete brushes;
		e->pData = NULL;

		// set entity origin
		GetVectorForKey( e, "origin", e->origin );
		// set entity eclass
		/*!\todo Make SetKeyValue check for "classname" change and assign appropriate eclass */
		e->eclass = Eclass_ForName( ValueForKey( e, "classname" ),
									( e->brushes.onext != &e->brushes ) );

		// go through all parsed brushes and build stuff
		for ( b = e->brushes.onext; b != &e->brushes; b = b->onext )
		{
			for ( f = b->brush_faces; f != NULL; f = f->next )
			{
				f->pShader = QERApp_Shader_ForName( f->texdef.GetName() );
				f->d_texture = f->pShader->getTexture();
			}

			// when brushes are in final state, build the planes and windings
			// NOTE: also converts BP brushes if g_qeglobals.bNeedConvert is true
			Brush_Build( b );
		}

//#define TERRAIN_HACK
#undef TERRAIN_HACK

#ifdef TERRAIN_HACK
		if ( ( strcmp( ValueForKey( e, "terrain" ),"1" ) == 0 && strcmp( e->eclass->name,"func_group" ) == 0 ) ) {

			// two aux pointers to the shaders used in the terrain entity
			// we don't keep refcount on them since they are only temporary
			// this avoids doing expensive lookups by name for all faces
			IShader *pTerrainShader, *pCaulk;

			pTerrainShader = NULL;
			pCaulk = QERApp_Shader_ForName( SHADER_CAULK );

			for ( b = e->brushes.onext; b != &e->brushes; b = b->onext )
			{
				if ( pTerrainShader == NULL ) {
					for ( f = b->brush_faces; f != NULL; f = f->next )
						if ( strcmp( f->texdef.GetName(), SHADER_CAULK ) != 0 ) {
							pTerrainShader = f->pShader;
						}
				}

				if ( pTerrainShader ) {
					for ( f = b->brush_faces; f != NULL; f = f->next )
					{
						if ( strcmp( f->texdef.GetName(), SHADER_CAULK ) != 0 ) { // not caulk
							Face_SetShader( f, pTerrainShader->getName() );
						}
						else{
							Face_SetShader( f, pCaulk->getName() );
						}
					}
				}
				else{
					Sys_FPrintf( SYS_WRN, "WARNING: no terrain shader found for brush\n" );
				}
			}
		}
#endif

#define PATCH_HACK
#ifdef PATCH_HACK
		for ( b = e->brushes.onext; b != &e->brushes; b = b->onext )
		{
			// patch hack, to be removed when dependency on brush_faces is removed
			if ( b->patchBrush ) {
				Patch_CalcBounds( b->pPatch, mins, maxs );
				for ( int i = 0; i < 3; i++ )
				{
					if ( (int)mins[i] == (int)maxs[i] ) {
						mins[i] -= 4;
						maxs[i] += 4;
					}
				}
				Brush_Resize( b, mins, maxs );
				Brush_Build( b );
			}
		}
#endif
		// add brush for fixedsize entity
		if ( e->eclass->fixedsize ) {
			vec3_t mins, maxs;
			VectorAdd( e->eclass->mins, e->origin, mins );
			VectorAdd( e->eclass->maxs, e->origin, maxs );
			b = Brush_Create( mins, maxs, &e->eclass->texdef );
			Entity_LinkBrush( e, b );
			Brush_Build( b );
		}

		for ( b = e->brushes.onext; b != &e->brushes; b = b->onext )
			Brush_AddToList( b, pBrushList );

		if ( strcmp( e->eclass->name, "worldspawn" ) == 0 ) {
			if ( world_entity ) {
				while ( e->brushes.onext != &e->brushes )
				{
					b = e->brushes.onext;
					Entity_UnlinkBrush( b );
					Entity_LinkBrush( world_entity, b );
				}
				Entity_Free( e );
			}
			else
			{
				world_entity = e;
			}
		}
		else if ( strcmp( e->eclass->name, "group_info" ) == 0 ) {
			// it's a group thing!
			Group_Add( e );
			Entity_Free( e );
		}
		else
		{
			// fix target/targetname collisions
			if ( ( g_PrefsDlg.m_bDoTargetFix ) && ( strcmp( ValueForKey( e, "target" ), "" ) != 0 ) ) {
				GPtrArray *t_ents = g_ptr_array_new();
				entity_t *e_target;
				const char *target = ValueForKey( e, "target" );
				qboolean bCollision = FALSE;

				// check the current map entities for an actual collision
				for ( e_target = entities.next; e_target != &entities; e_target = e_target->next )
				{
					if ( !strcmp( target, ValueForKey( e_target, "target" ) ) ) {
						bCollision = TRUE;
						// make sure the collision is not between two imported entities
						for ( j = 0; j < (int)new_ents->len; j++ )
						{
							if ( e_target == g_ptr_array_index( new_ents, j ) ) {
								bCollision = FALSE;
							}
						}
					}
				}

				// find the matching targeted entity(s)
				if ( bCollision ) {
					for ( j = num_ents - 1; j > 0; j-- )
					{
						e_target = (entity_t*)ents->GetAt( j );
						if ( e_target != NULL && e_target != e ) {
							const char *targetname = ValueForKey( e_target, "targetname" );
							if ( ( targetname != NULL ) && ( strcmp( target, targetname ) == 0 ) ) {
								g_ptr_array_add( t_ents, (gpointer)e_target );
							}
						}
					}
					if ( t_ents->len > 0 ) {
						// link the first to get a unique target/targetname
						Entity_Connect( e, (entity_t*)g_ptr_array_index( t_ents,0 ) );
						// set the targetname of the rest of them manually
						for ( j = 1; j < (int)t_ents->len; j++ )
							SetKeyValue( (entity_t*)g_ptr_array_index( t_ents, j ), "targetname", ValueForKey( e, "target" ) );
					}
					g_ptr_array_free( t_ents, FALSE );
				}
			}

			// add the entity to the end of the entity list
			Entity_AddToList( e, &entities );
			g_qeglobals.d_num_entities++;

			// keep a list of ents added to avoid testing collisions against them
			g_ptr_array_add( new_ents, (gpointer)e );
		}
	}
	g_ptr_array_free( new_ents, FALSE );

	ents->RemoveAll();

	g_qeglobals.bNeedConvert = false;
}