⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entity.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		geVec3d_Subtract(&mOrigin, &wPoint, &wPoint);

		return	geVec3d_Length(&wPoint);
	}
	else
	{
		return	0;
	}
}

// check whether or not this entity is within this
// bounding box
//==================================================================
// When we are done moving the entity we want to snap it to the
// grid etc.
//==================================================================
#define RoundDouble(x)  (floor( (x) + 0.5 ))

static float SnapToGrid
	(
	  float x,
	  double GridSize
	)
{
	return (float)(RoundDouble ((x/GridSize) ) * GridSize) ;
}

void CEntity::DoneMove(double GridSize, const EntityTable *pEntityDefs)
{
	float x, y, z;

	// Snap to the grid
	x = SnapToGrid (mOrigin.X, GridSize);
	y = SnapToGrid (mOrigin.Y, GridSize);
	z = SnapToGrid (mOrigin.Z, GridSize);

	SetOrigin (x, y, z, pEntityDefs);
}

// update our origin
void CEntity::UpdateOriginFirst(const EntityTable *pEntityDefs)
{
	// find our origin
	CString OriginStr;

	// if we empty leave
	if (!GetOriginString (OriginStr, pEntityDefs)) 
	{
		EntityStyle = ENTITY_S_BRUSH;
		return;
	}
	else 
	{
		EntityStyle = ENTITY_S_ORIGIN;
	}

	// get our x y z
	int x, y, z;
	sscanf(OriginStr, "%d %d %d", &x, &y, &z);

	SetOrigin ((float)x, (float)y, (float)z, pEntityDefs);
}


#define CENTITYTYPE "CEntity"
#define CENTSTYLE "eStyle"
#define CENTORIGIN "eOrigin"
#define CENTRENDERORIGIN "eRenderOrigin"
#define CENTPAIRCOUNT "ePairCount"
#define CENTFLAGS "eFlags"
#define CENTGROUP "eGroup"
#define CENTKEY "K"
#define CENTVALUE "V"
#define CENDENTTYPE "End CEntity"

// -------------------------------------------------------------------------------
// saves the entity out to a specified file stream
geBoolean CEntity::SaveToFile( FILE *file )
{
	ASSERT( file );

	int	Count;	// number of keys

	if (fprintf(file, "CEntity\neStyle %d\n", EntityStyle ) < 0) return GE_FALSE;
	if (fprintf(file, "eOrigin %d %d %d 2\n",
		Units_Round( mOrigin.X ), Units_Round( mOrigin.Y ), Units_Round( mOrigin.Z ) ) < 0) return GE_FALSE;

	if (fprintf(file, "eFlags %d\n",  mFlags) < 0) return GE_FALSE;
	if (fprintf(file, "eGroup %d\n",  mGroup) < 0) return GE_FALSE;

	Count	= GetNumKeyValuePairs ();
	if (fprintf(file, "ePairCount %d\n", Count) < 0) return GE_FALSE;

	for (int j = 0; j < Count; j++)
	{
		CString Key, Value;

		if (GetKeyValuePair (j, Key, Value))
		{
			char QuotedValue[SCANNER_MAXDATA];

			Util_QuoteString (Value, QuotedValue);
			if (fprintf (file, "Key %s Value %s\n", (LPCSTR)Key, QuotedValue) < 0) return GE_FALSE;
		}
	}
	return GE_TRUE;
}


static char *StripNewline
	(
	  char *s
	)
// terminates the string at the first cr or lf character
{
	char *c;

	ASSERT (s != NULL);

	c = s;
	while (*c != '\0')
	{
		switch (*c)
		{
			case '\r' :
			case '\n' :
				*c = '\0';
				break;
			default :
				++c;
				break;
		}
	}
	return s;
}

// -----------------------------------------------------------------------------------
// reads the entity in from a specified file stream
geBoolean CEntity::ReadFromFile
	(
	  Parse3dt *Parser,
	  int VersionMajor,
	  int VersionMinor,
	  const char **Expected,
	  const EntityTable *pEntityDefs
	)
{
	int Trash;
	int	Count;

	assert (Parser != NULL);

	if (!Parse3dt_ScanExpectingText (Parser, (*Expected = "CEntity"))) return GE_FALSE;
	if (!Parse3dt_GetInt (Parser, (*Expected = "eStyle"), &Trash)) return GE_FALSE;
	EntityStyle = (enum EntityStyles)Trash;

	if (!Parse3dt_GetVec3d (Parser, (*Expected = "eOrigin"), &mOrigin)) return GE_FALSE;
	if (!Parse3dt_GetInt (Parser, NULL, &Trash)) return GE_FALSE;

	if ((VersionMajor == 1) && (VersionMinor < 21))
	{
		geVec3d TrashVec;
		if (!Parse3dt_GetVec3d (Parser, (*Expected = "eRenderOrigin"), &TrashVec)) return GE_FALSE;
		if (!Parse3dt_GetInt (Parser, NULL, &Trash)) return GE_FALSE;
	}

	// need to flip Z on file versions prior to 1.4
	if ((VersionMajor==1) && (VersionMinor < 4))
	{
		mOrigin.Z		=-mOrigin.Z;
	}

	if (!Parse3dt_GetInt (Parser, (*Expected = "eFlags"), &mFlags)) return GE_FALSE;
	if (!Parse3dt_GetInt (Parser, (*Expected = "eGroup"), &mGroup)) return GE_FALSE;

	if( (VersionMajor==1) && (VersionMinor <= 6 ) )
	{
		if( mGroup == -1 )	// "No group" was -1 and now is 0
			mGroup = 0 ;
	}

	if (!Parse3dt_GetInt (Parser, (*Expected = "ePairCount"), &Count)) return GE_FALSE;

	if ((VersionMajor == 1) && (VersionMinor < 14))
	{
		// old key/value stuff
		FILE *file;

		file = Scanner_GetFile (Parser->Scanner);

		for( int j = 0; j < Count; j++)
		{
			char Key[255];
			char Value[255];

			fscanf( file, "K " );
			fgets( Key, 255, file );
			StripNewline (Key);

			fscanf( file, "V " );
			fgets( Value, 255, file );
			StripNewline (Value);

			this->SetKeyValue (Key, Value);
		}
	}
	else
	{
		int j;
		char Key[SCANNER_MAXDATA];
		char Value[SCANNER_MAXDATA];

		for (j = 0; j < Count; ++j)
		{
			if (!Parse3dt_GetIdentifier (Parser, (*Expected = "Key"), Key)) return GE_FALSE;
			if (!Parse3dt_GetLiteral (Parser, (*Expected = "Value"), Value)) return GE_FALSE;
			SetKeyValue (Key, Value);
		}
	}
	/*
	  If the Z was flipped above (i.e. this is a version 1.3 file or earlier,
	  then the Z in the origin key string (if it exists) will not agree
	  with mOrigin.Z.
	  So here we make sure they agree.  This has the effect of making the
	  origin key string superfluous on save/restore, but wtf.
	*/

	//versions < 1.10 need to convert to texels from centimeters
	if ((VersionMajor==1) && (VersionMinor < 10))
	{
		geVec3d_Scale (&mOrigin, Units_CentimetersToEngine (1.0f), &mOrigin);
	}
	SetOrigin (mOrigin.X, mOrigin.Y, mOrigin.Z, pEntityDefs);

	return GE_TRUE;
}

void CEntity::SetGroupId 
	(
	  int id
	)
{
	this->mGroup = id;
}

int CEntity::GetGroupId 
	(
	  void
	) const 
{
	return this->mGroup;
}

void CEntity::SetVisible 
	(
	  BOOL flag
	)
{
	if (flag)
	{
		this->mFlags &= ~ENTITY_HIDDEN;
	}
	else
	{
		this->mFlags |= ENTITY_HIDDEN;
	}	
}

BOOL CEntity::IsVisible 
	(
	  void
	) const
{
	return !(this->mFlags & ENTITY_HIDDEN);
}

void CEntity::SetLock
	(
	  BOOL flag
	)
{
	if (flag)
	{
		this->mFlags |= ENTITY_LOCKED;
	}
	else
	{
		this->mFlags &= ~ENTITY_LOCKED;
	}
}

BOOL CEntity::IsLocked 
	(
	  void
	) const
{
	return (this->mFlags & ENTITY_LOCKED);
}

static CEntity const *EntityList_FindByName
	(
	  CEntityArray  *pEnts,
	  char const *pName
	)
{
	for (int i = 0; i < pEnts->GetSize (); ++i)
	{
		CEntity const *pEnt;
		CString Name;

//		pEnt = &((*mEntityArray)[CurrentEnt]);
		pEnt = &((*pEnts)[i]);
		pEnt->GetKeyValue ("%name%", Name);
		if (stricmp (pName, Name) == 0)
		{
			return pEnt;
		}
	}
	return NULL;
}


CEntity * EntityList_FindByClassName
	(
	  CEntityArray  *	pEnts,
	  const char	*	pName
	)
{
	CEntity * pEnt;

	for (int i = 0; i < pEnts->GetSize (); ++i)
	{
		pEnt = &((*pEnts)[i]);
		if( pEnt->GetClassname().Compare( pName ) == 0 )
		{
			return pEnt;
		}
	}
	return NULL;
}/* EntityList_FindByClassName */


BOOL CEntity::IsValidKey
	(
	  CString const &Key,
	  ModelList const *pModels, 
	  CEntityArray const *pEnts,
	  const EntityTable *pEntityDefs
	) const
// returns TRUE if the key is one of the specials, or if it has type information
{
	BOOL Success;
	TopType EntityType;
	CString EntityClassname = GetClassname ();

	if ((Key == CLASSNAME) || (Key == "%name%"))
	{
		Success = TRUE;
	}
	else
	{
		Success = EntityTable_GetEntityPropertyType (pEntityDefs, EntityClassname, Key, &EntityType);
		if (Success)
		{
			CString Value;

			GetKeyValue (Key, Value);
			switch (EntityType)
			{
				case T_STRUCT :
				{
					// look for an entity with this name...
					CEntity const *Target;

					// yeah, I know the cast is ugly.
					// FindByName didn't like taking the address of something in a
					// const array.  I don't know what the deal is...
					Target = EntityList_FindByName (const_cast<CEntityArray *>(pEnts), Value);
					Success = (Target != NULL);
					break;
				}

				case T_MODEL :
				{
					// look for model of this name in models list
					Model *pModel;

					pModel = ModelList_FindByName (pModels, Value);
					Success = (pModel != NULL);
					break;
				}

				default :
					break;
			}
		}
	}
	return Success;
}

int CEntity::GetNumValidKeyValuePairs
	(
	  ModelList const *pModels, 
	  CEntityArray const *pEnts,
	  const EntityTable *pEntityDefs
	) const
{
	int j;
	int NumKeys;
	int NumValidKeys;

	NumValidKeys = 0;
	NumKeys = GetNumKeyValuePairs ();
	for (j = 0; j < NumKeys; j++)
	{
		CString Key, Value;

		if (GetKeyValuePair (j, Key, Value))
		{
			BOOL Success;

			// only count those that have type information entries
			Success = IsValidKey (Key, pModels, pEnts, pEntityDefs);

			if (Success)
			{
				++NumValidKeys;
			}
		}		
	}
	return NumValidKeys;
}

// writes the entity out to the map file
void CEntity::WriteToMap 
	(
	  FILE *exfile, 
	  ModelList const *pModels, 
	  CEntityArray const *pEnts,
	  const EntityTable *pEntityDefs
	) const
{
	int NumValidKeys;
	int NumKeys;
#ifdef _DEBUG
	int NumKeysWritten;
#endif
	CString EntityClassname = GetClassname ();

	TypeIO_WriteInt (exfile, 0);	// numbrushes
	TypeIO_WriteInt (exfile, 0);	// no motion data today

	// output entity key/value pairs
	// We output only those keys that have type information entries.
	NumValidKeys = GetNumValidKeyValuePairs (pModels, pEnts, pEntityDefs);
	TypeIO_WriteInt (exfile, NumValidKeys);	//number of keys
	
	NumKeys = GetNumKeyValuePairs ();

#ifdef _DEBUG
	NumKeysWritten = 0;
#endif

	for(int j = 0; j < NumKeys; j++)
	{
		CString Key, Value;

		if (GetKeyValuePair (j, Key, Value))
		{
			// only output those that have type information entries
			BOOL Success;

			Success = IsValidKey (Key, pModels, pEnts, pEntityDefs);
		
			if (Success)
			{						
				char ValueString [100];  // string to store value
				TopType KeyType;

				// get the type.
				// Since classname and %name% don't have type info,
				// we need to check success flag ...
				Success = EntityTable_GetEntityPropertyType (pEntityDefs, GetClassname(), Key, &KeyType);

				// Boolean keys are converted to integer
				if (Success && (KeyType == T_BOOLEAN))
				{
					if (Value == "True")
					{
						strcpy (ValueString, "1");
					}
					else
					{
						strcpy (ValueString, "0");
					}
				}
				else
				{
					strcpy (ValueString, Value);
				}

				// output name and value
				TypeIO_WriteString (exfile, Key);
				TypeIO_WriteString (exfile, ValueString);
#ifdef _DEBUG
				++NumKeysWritten;
#endif
			}
		}
	}
#ifdef _DEBUG
	assert (NumKeysWritten == NumValidKeys);
#endif
}


int EntityList_Enum
	(
		CEntityArray&       EntityArray,
		void *				lParam,
		EntityList_CB		CallBack
	)
{
	geBoolean bResult = GE_TRUE ;	// TRUE means entire list was processed
	int	i ;

	for( i=0; i< EntityArray.GetSize(); i++ )
	{
		if( (bResult = CallBack( EntityArray[i], lParam )) == GE_FALSE )
			break ;		
	}

	return bResult ;
}

const geBitmap *CEntity::GetBitmapPtr (const EntityTable *pEntityDefs) const
{

	return EntityTable_GetBitmapPtr (pEntityDefs, GetClassname ());
}

⌨️ 快捷键说明

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