map.cpp

来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 1,043 行 · 第 1/2 页

CPP
1,043
字号
	VectorCopy (vec3_origin, g_pParentWnd->GetCamera()->Camera().origin);
	g_pParentWnd->GetCamera()->Camera().origin[2] = 48;
	VectorCopy (vec3_origin, g_pParentWnd->GetXYWnd()->GetOrigin());

	Map_RestoreBetween ();

  Group_Init();

	Sys_UpdateWindows (W_ALL);
	modified = false;
}

/*
===========================================================

  REGION

===========================================================
*/

qboolean	region_active;
vec3_t	region_mins = {MIN_WORLD_COORD, MIN_WORLD_COORD, MIN_WORLD_COORD};
vec3_t	region_maxs = {MAX_WORLD_COORD, MAX_WORLD_COORD, MAX_WORLD_COORD};

brush_t	*region_sides[4];
/*
===========
AddRegionBrushes

a regioned map will have temp walls put up at the region boundary
===========
*/
void AddRegionBrushes (void)
{
	vec3_t	mins, maxs;
	int		i;
	texdef_t	td;

	if (!region_active)
		return;

	memset (&td, 0, sizeof(td));
	//strcpy (td.name, "REGION");
	td.SetName("REGION");

	mins[0] = region_mins[0] - 16;
	maxs[0] = region_mins[0] + 1;
	mins[1] = region_mins[1] - 16;
	maxs[1] = region_maxs[1] + 16;
	mins[2] = MIN_WORLD_COORD;
	maxs[2] = MAX_WORLD_COORD;
	region_sides[0] = Brush_Create (mins, maxs, &td);

	mins[0] = region_maxs[0] - 1;
	maxs[0] = region_maxs[0] + 16;
	region_sides[1] = Brush_Create (mins, maxs, &td);

	mins[0] = region_mins[0] - 16;
	maxs[0] = region_maxs[0] + 16;
	mins[1] = region_mins[1] - 16;
	maxs[1] = region_mins[1] + 1;
	region_sides[2] = Brush_Create (mins, maxs, &td);

	mins[1] = region_maxs[1] - 1;
	maxs[1] = region_maxs[1] + 16;
	region_sides[3] = Brush_Create (mins, maxs, &td);

	for (i=0 ; i<4 ; i++)
	{
		Brush_AddToList (region_sides[i], &selected_brushes);
		Entity_LinkBrush (world_entity, region_sides[i]);
		Brush_Build( region_sides[i] );
	}
}

void RemoveRegionBrushes (void)
{
	int		i;

	if (!region_active)
		return;
	for (i=0 ; i<4 ; i++)
		Brush_Free (region_sides[i]);
}


qboolean Map_IsBrushFiltered (brush_t *b)
{
	int		i;

	for (i=0 ; i<3 ; i++)
	{
		if (b->mins[i] > region_maxs[i])
			return true;
		if (b->maxs[i] < region_mins[i])
			return true;
	}
	return false;
}

/*
===========
Map_RegionOff

Other filtering options may still be on
===========
*/
void Map_RegionOff (void)
{
	brush_t	*b, *next;
	int			i;

	region_active = false;
	for (i=0 ; i<3 ; i++)
	{
		region_maxs[i] = MAX_WORLD_COORD;//4096;
		region_mins[i] = MIN_WORLD_COORD;//-4096;
	}
	
	for (b=filtered_brushes.next ; b != &filtered_brushes ; b=next)
	{
		next = b->next;
		if (Map_IsBrushFiltered (b))
			continue;		// still filtered
		Brush_RemoveFromList (b);
    if (active_brushes.next == NULL || active_brushes.prev == NULL)
    {
      active_brushes.next = &active_brushes;
      active_brushes.prev = &active_brushes;
    }
		Brush_AddToList (b, &active_brushes);
	}

	Sys_UpdateWindows (W_ALL);
}

void Map_ApplyRegion (void)
{
	brush_t	*b, *next;

	region_active = true;
	for (b=active_brushes.next ; b != &active_brushes ; b=next)
	{
		next = b->next;
		if (!Map_IsBrushFiltered (b))
			continue;		// still filtered
		Brush_RemoveFromList (b);
		Brush_AddToList (b, &filtered_brushes);
	}

	Sys_UpdateWindows (W_ALL);
}


/*
========================
Map_RegionSelectedBrushes
========================
*/
void Map_RegionSelectedBrushes (void)
{
	Map_RegionOff ();

	if (selected_brushes.next == &selected_brushes)  // nothing selected
  {
    Sys_Printf("Tried to region with no selection...\n");
    return;
  }
	region_active = true;
	Select_GetBounds (region_mins, region_maxs);

	// move the entire active_brushes list to filtered_brushes
	filtered_brushes.next = active_brushes.next;
	filtered_brushes.prev = active_brushes.prev;
	filtered_brushes.next->prev = &filtered_brushes;
	filtered_brushes.prev->next = &filtered_brushes;

	// move the entire selected_brushes list to active_brushes
	active_brushes.next = selected_brushes.next;
	active_brushes.prev = selected_brushes.prev;
	active_brushes.next->prev = &active_brushes;
	active_brushes.prev->next = &active_brushes;

	// clear selected_brushes
	selected_brushes.next = selected_brushes.prev = &selected_brushes;

	Sys_UpdateWindows (W_ALL);
}


/*
===========
Map_RegionXY
===========
*/
void Map_RegionXY (void)
{
	Map_RegionOff ();

	region_mins[0] = g_pParentWnd->GetXYWnd()->GetOrigin()[0] - 0.5 * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale();
	region_maxs[0] = g_pParentWnd->GetXYWnd()->GetOrigin()[0] + 0.5 * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale();
	region_mins[1] = g_pParentWnd->GetXYWnd()->GetOrigin()[1] - 0.5 * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale();
	region_maxs[1] = g_pParentWnd->GetXYWnd()->GetOrigin()[1] + 0.5 * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale();
	region_mins[2] = -MIN_WORLD_COORD;
	region_maxs[2] = MAX_WORLD_COORD;
	Map_ApplyRegion ();
}

/*
===========
Map_RegionTallBrush
===========
*/
void Map_RegionTallBrush (void)
{
	brush_t	*b;

	if (!QE_SingleBrush ())
		return;

	b = selected_brushes.next;

	Map_RegionOff ();

	VectorCopy (b->mins, region_mins);
	VectorCopy (b->maxs, region_maxs);
	region_mins[2] = MIN_WORLD_COORD;
	region_maxs[2] = MAX_WORLD_COORD;


	Select_Delete ();
	Map_ApplyRegion ();
}
/*
===========
Map_RegionBrush
===========
*/
void Map_RegionBrush (void)
{
	brush_t	*b;

	if (!QE_SingleBrush ())
		return;

	b = selected_brushes.next;

	Map_RegionOff ();

	VectorCopy (b->mins, region_mins);
	VectorCopy (b->maxs, region_maxs);

	Select_Delete ();
	Map_ApplyRegion ();
}



void UniqueTargetName(CString& rStr)
{
	// make a unique target value
	int maxtarg = 0;
	for (entity_t* e=entities.next ; e != &entities ; e=e->next)
	{
		char* tn = ValueForKey (e, "targetname");
		if (tn && tn[0])
		{
			int targetnum = atoi(tn+1);
			if (targetnum > maxtarg)
				maxtarg = targetnum;
		}
    else
    {
		  tn = ValueForKey (e, "target");
		  if (tn && tn[0])
		  {
			  int targetnum = atoi(tn+1);
			  if (targetnum > maxtarg)
				  maxtarg = targetnum;
		  }
    }
	}
  rStr.Format("t%i", maxtarg+1);
}

//
//================
//Map_ImportFile
// Timo 09/01/99 : called by CXYWnd::Paste & Map_ImportFile
// if Map_ImportFile ( prefab ), the buffer may contain brushes in old format ( conversion needed )
//================
//
void Map_ImportBuffer (char* buf)
{
	entity_t* ent;
	brush_t* b = NULL;
	CPtrArray ptrs;

	Select_Deselect();

	Undo_Start("import buffer");

	g_qeglobals.d_parsed_brushes = 0;
	if (buf)
	{
		CMapStringToString mapStr;
		StartTokenParsing (buf);
		g_qeglobals.d_num_entities = 0;

		// Timo
		// will be used in Entity_Parse to detect if a conversion between brush formats is needed
		g_qeglobals.bNeedConvert = false;
		g_qeglobals.bOldBrushes = false;
		g_qeglobals.bPrimitBrushes = false;

		while (1)
		{

			// use the selected brushes list as it's handy
			//ent = Entity_Parse (false, &selected_brushes);
			ent = Entity_Parse (false, &active_brushes);
			if (!ent)
				break;
			//end entity for undo
			Undo_EndEntity(ent);
			//end brushes for undo
			for(b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext)
			{
				Undo_EndBrush(b);
			}

			if (!strcmp(ValueForKey (ent, "classname"), "worldspawn"))
			{
				// world brushes need to be added to the current world entity

				b=ent->brushes.onext;
				while (b && b != &ent->brushes)
				{
					brush_t* bNext = b->onext;
					Entity_UnlinkBrush(b);
					Entity_LinkBrush(world_entity, b);
					ptrs.Add(b);
					b = bNext;
				}
			}
			else
			{
				// the following bit remaps conflicting target/targetname key/value pairs
				CString str = ValueForKey(ent, "target");
				CString strKey;
				CString strTarget("");
				if (str.GetLength() > 0)
				{
					if (FindEntity("target", str.GetBuffer(0)))
					{
						if (!mapStr.Lookup(str, strKey))
						{
							UniqueTargetName(strKey);
							mapStr.SetAt(str, strKey);
						}
						strTarget = strKey;
						SetKeyValue(ent, "target", strTarget.GetBuffer(0));
					}
				}
				str = ValueForKey(ent, "targetname");
				if (str.GetLength() > 0)
				{
					if (FindEntity("targetname", str.GetBuffer(0)))
					{
						if (!mapStr.Lookup(str, strKey))
						{
							UniqueTargetName(strKey);
							mapStr.SetAt(str, strKey);
						}
						SetKeyValue(ent, "targetname", strKey.GetBuffer(0));
					}
				}
				//if (strTarget.GetLength() > 0)
				//  SetKeyValue(ent, "target", strTarget.GetBuffer(0));

				// add the entity to the end of the entity list
				ent->next = &entities;
				ent->prev = entities.prev;
				entities.prev->next = ent;
				entities.prev = ent;
				g_qeglobals.d_num_entities++;

				for (b=ent->brushes.onext ; b != &ent->brushes ; b=b->onext)
				{
					ptrs.Add(b);
				}
			}
		}
	}

	//::ShowWindow(g_qeglobals.d_hwndEntity, FALSE);
	//::LockWindowUpdate(g_qeglobals.d_hwndEntity);
	g_bScreenUpdates = false; 
	for (int i = 0; i < ptrs.GetSize(); i++)
	{
		Brush_Build(reinterpret_cast<brush_t*>(ptrs[i]), true, false);
		Select_Brush(reinterpret_cast<brush_t*>(ptrs[i]), true, false);
	}
	//::LockWindowUpdate(NULL);
	g_bScreenUpdates = true; 

	ptrs.RemoveAll();

	// reset the "need conversion" flag
	// conversion to the good format done in Map_BuildBrushData
	g_qeglobals.bNeedConvert=false;

	Sys_UpdateWindows (W_ALL);
  //Sys_MarkMapModified();
	modified = true;

	Undo_End();

}


//
//================
//Map_ImportFile
//================
//
void Map_ImportFile (char *filename)
{
  char* buf;
	char temp[1024];
	Sys_BeginWait ();
	QE_ConvertDOSToUnixName( temp, filename );
  if (LoadFile (filename, (void **)&buf) != -1)
  {
    Map_ImportBuffer(buf);
    free(buf);
    Map_BuildBrushData();
  }
	Sys_UpdateWindows (W_ALL);
	modified = true;
	Sys_EndWait();
}

//
//===========
//Map_SaveSelected
//===========
//
// Saves selected world brushes and whole entities with partial/full selections
//
void Map_SaveSelected(char* pFilename)
{
	entity_t	*e, *next;
	FILE *f;
	char temp[1024];
	int count;

	QE_ConvertDOSToUnixName(temp, pFilename);
	f = fopen(pFilename, "w");

	if (!f)
	{
		Sys_Printf ("ERROR!!!! Couldn't open %s\n", pFilename);
		return;
	}

	// write world entity first
	Entity_WriteSelected(world_entity, f);

	// then write all other ents
	count = 1;
	for (e=entities.next ; e != &entities ; e=next)
	{
  	fprintf (f, "// entity %i\n", count);
   	count++;
 		Entity_WriteSelected(e, f);
		next = e->next;
	}
	fclose (f);
}


//
//===========
//Map_SaveSelected
//===========
//
// Saves selected world brushes and whole entities with partial/full selections
//
void Map_SaveSelected(CMemFile* pMemFile, CMemFile* pPatchFile)
{
	entity_t	*e, *next;
	int count;
	CString strTemp;
  
	// write world entity first
	Entity_WriteSelected(world_entity, pMemFile);

	// then write all other ents
	count = 1;
	for (e=entities.next ; e != &entities ; e=next)
	{
		MemFile_fprintf(pMemFile, "// entity %i\n", count);
		count++;
 		Entity_WriteSelected(e, pMemFile);
		next = e->next;
	}

  //if (pPatchFile)
  //  Patch_WriteFile(pPatchFile);
}


void MemFile_fprintf(CMemFile* pMemFile, const char* pText, ...)
{
  char Buffer[4096];
  va_list args;
	va_start (args,pText);
  vsprintf(Buffer, pText, args);
  pMemFile->Write(Buffer, strlen(Buffer));
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?