mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-11-26 22:01:38 +00:00
8037810110
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/ZeroRadiant@177 8a3a26a2-13c4-0310-b231-cf6edde360e5
675 lines
16 KiB
C++
675 lines
16 KiB
C++
/*
|
|
BobToolz plugin for GtkRadiant
|
|
Copyright (C) 2001 Gordon Biggans
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
// DEntity.cpp: implementation of the DEntity class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#ifdef _WIN32
|
|
#pragma warning(disable : 4786)
|
|
#endif
|
|
|
|
#include "DEntity.h"
|
|
|
|
#include "dialogs-gtk.h"
|
|
#include "misc.h"
|
|
#include "CPortals.h"
|
|
|
|
const char* brushEntityList[] = {
|
|
"worldspawn",
|
|
"trigger_always",
|
|
"trigger_hurt",
|
|
"trigger_multiple",
|
|
"trigger_push",
|
|
"trigger_teleport",
|
|
"func_bobbing",
|
|
"func_button",
|
|
"func_door",
|
|
"func_group",
|
|
"func_pendulum",
|
|
"func_plat",
|
|
"func_rotating",
|
|
"func_static",
|
|
"func_timer",
|
|
"func_train",
|
|
0
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
DEntity::DEntity(char *classname, int ID)
|
|
{
|
|
SetClassname(classname);
|
|
m_nID = ID;
|
|
QER_Entity = NULL;
|
|
}
|
|
|
|
DEntity::~DEntity()
|
|
{
|
|
ClearPatches();
|
|
ClearBrushes();
|
|
ClearEPairs();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Implementation
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
void DEntity::ClearBrushes()
|
|
{
|
|
for(list<DBrush *>::const_iterator deadBrush=brushList.begin(); deadBrush!=brushList.end(); deadBrush++)
|
|
{
|
|
delete *deadBrush;
|
|
}
|
|
brushList.clear();
|
|
}
|
|
|
|
void DEntity::ClearPatches()
|
|
{
|
|
for(list<DPatch *>::const_iterator deadPatch=patchList.begin(); deadPatch!=patchList.end(); deadPatch++)
|
|
{
|
|
delete *deadPatch;
|
|
}
|
|
patchList.clear();
|
|
}
|
|
|
|
DPatch* DEntity::NewPatch()
|
|
{
|
|
DPatch* newPatch = new DPatch;
|
|
|
|
patchList.push_back(newPatch);
|
|
|
|
return newPatch;
|
|
}
|
|
|
|
DBrush* DEntity::NewBrush(int ID)
|
|
{
|
|
DBrush* newBrush = new DBrush(ID);
|
|
|
|
brushList.push_back(newBrush);
|
|
|
|
return newBrush;
|
|
}
|
|
|
|
char* getNextBracket(char* s)
|
|
{
|
|
char* p = s;
|
|
while(*p)
|
|
{
|
|
p++;
|
|
if(*p == '(')
|
|
break;
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
bool DEntity::LoadFromPrt(char *filename)
|
|
{
|
|
CPortals portals;
|
|
strcpy(portals.fn, filename);
|
|
portals.Load();
|
|
|
|
if(portals.node_count == 0)
|
|
return FALSE;
|
|
|
|
ClearBrushes();
|
|
ClearEPairs();
|
|
|
|
bool build = false;
|
|
for(unsigned int i = 0; i < portals.node_count; i++)
|
|
{
|
|
build = false;
|
|
DBrush* brush = NewBrush();
|
|
|
|
for(unsigned int j = 0; j < portals.node[i].portal_count; j++)
|
|
{
|
|
for(unsigned int k = 0; k < portals.node[i].portal[j].point_count-2; k++)
|
|
{
|
|
vec3_t v1, v2, normal, n;
|
|
VectorSubtract(portals.node[i].portal[j].point[k+2].p, portals.node[i].portal[j].point[k+1].p, v1);
|
|
VectorSubtract(portals.node[i].portal[j].point[k].p, portals.node[i].portal[j].point[k+1].p, v2);
|
|
CrossProduct(v1, v2, n);
|
|
VectorNormalize(n, v2);
|
|
|
|
if(k == 0)
|
|
{
|
|
VectorCopy(v2, normal);
|
|
}
|
|
else
|
|
{
|
|
VectorSubtract(v2, normal, v1);
|
|
if(VectorLength(v1) > 0.01)
|
|
{
|
|
build = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!build)
|
|
brush->AddFace(portals.node[i].portal[j].point[2].p, portals.node[i].portal[j].point[1].p, portals.node[i].portal[j].point[0].p, "textures/common/caulk", FALSE);
|
|
else
|
|
brush->AddFace(portals.node[i].portal[j].point[0].p, portals.node[i].portal[j].point[1].p, portals.node[i].portal[j].point[2].p, "textures/common/caulk", FALSE);
|
|
}
|
|
if(build)
|
|
brush->BuildInRadiant(FALSE, NULL);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
DPlane* DEntity::AddFaceToBrush(vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData* faceData, int ID)
|
|
{
|
|
DBrush* buildBrush = GetBrushForID(ID);
|
|
return buildBrush->AddFace(va, vb, vc, faceData);
|
|
// slow, dont use much
|
|
}
|
|
|
|
DBrush* DEntity::GetBrushForID(int ID)
|
|
{
|
|
DBrush* buildBrush = NULL;
|
|
|
|
for(list<DBrush *>::const_iterator chkBrush=brushList.begin(); chkBrush!=brushList.end(); chkBrush++)
|
|
{
|
|
if((*chkBrush)->m_nBrushID == ID)
|
|
{
|
|
buildBrush = (*chkBrush);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!buildBrush)
|
|
buildBrush = NewBrush(ID);
|
|
|
|
return buildBrush;
|
|
}
|
|
|
|
void DEntity::LoadSelectedBrushes()
|
|
{
|
|
ClearBrushes();
|
|
ClearEPairs();
|
|
|
|
int count = g_FuncTable.m_pfnAllocateSelectedBrushHandles();
|
|
|
|
for(int i = 0; i < count; i++) {
|
|
brush_t *brush = (brush_t*)g_FuncTable.m_pfnGetSelectedBrushHandle(i);
|
|
|
|
if(brush->pPatch)
|
|
continue;
|
|
|
|
DBrush* loadBrush = NewBrush(i);
|
|
loadBrush->LoadFromBrush_t(brush, TRUE);
|
|
}
|
|
|
|
g_FuncTable.m_pfnReleaseSelectedBrushHandles();
|
|
}
|
|
|
|
void DEntity::LoadSelectedPatches()
|
|
{
|
|
ClearPatches();
|
|
ClearEPairs();
|
|
|
|
int count = g_FuncTable.m_pfnAllocateSelectedPatchHandles();
|
|
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
//$ FIXME: m_pfnGetPatchHandle
|
|
patchMesh_t *pmesh = (patchMesh_t*)g_FuncTable.m_pfnGetPatchData(i);
|
|
|
|
DPatch* loadPatch = NewPatch();
|
|
loadPatch->LoadFromBrush_t(pmesh->pSymbiot);
|
|
}
|
|
|
|
g_FuncTable.m_pfnReleasePatchHandles();
|
|
}
|
|
|
|
bool* DEntity::BuildIntersectList()
|
|
{
|
|
int max = GetIDMax();
|
|
if(max == 0)
|
|
return NULL;
|
|
|
|
bool* pbIntList = new bool[max];
|
|
memset(pbIntList, 0, sizeof(bool)*(max));
|
|
|
|
for(list<DBrush *>::const_iterator pB1=brushList.begin(); pB1!=brushList.end(); pB1++)
|
|
{
|
|
list<DBrush *>::const_iterator pB2=pB1;
|
|
for(pB2++; pB2!=brushList.end(); pB2++)
|
|
{
|
|
if((*pB1)->IntersectsWith((*pB2)))
|
|
{
|
|
pbIntList[(*pB1)->m_nBrushID] = TRUE;
|
|
pbIntList[(*pB2)->m_nBrushID] = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pbIntList;
|
|
}
|
|
|
|
bool* DEntity::BuildDuplicateList()
|
|
{
|
|
int max = GetIDMax();
|
|
if(max == 0)
|
|
return NULL;
|
|
|
|
bool* pbDupList = new bool[max];
|
|
memset(pbDupList, 0, sizeof(bool)*(max));
|
|
|
|
for(list<DBrush *>::const_iterator pB1=brushList.begin(); pB1!=brushList.end(); pB1++)
|
|
{
|
|
list<DBrush *>::const_iterator pB2=pB1;
|
|
for(pB2++; pB2!=brushList.end(); pB2++)
|
|
{
|
|
if(**pB1 == *pB2)
|
|
{
|
|
pbDupList[(*pB1)->m_nBrushID] = TRUE;
|
|
pbDupList[(*pB2)->m_nBrushID] = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pbDupList;
|
|
}
|
|
|
|
void DEntity::SelectBrushes(bool *selectList)
|
|
{
|
|
if(selectList == NULL)
|
|
return;
|
|
|
|
g_FuncTable.m_pfnDeselectAllBrushes();
|
|
|
|
g_FuncTable.m_pfnAllocateActiveBrushHandles();
|
|
|
|
for(std::list<DBrush *>::const_iterator pBrush=brushList.begin(); pBrush!=brushList.end(); pBrush++)
|
|
{
|
|
if(selectList[(*pBrush)->m_nBrushID])
|
|
g_FuncTable.m_pfnSelectBrush((*pBrush)->QER_brush);
|
|
}
|
|
g_FuncTable.m_pfnReleaseActiveBrushHandles();
|
|
}
|
|
|
|
bool DEntity::LoadFromEntity(int id, bool bLoadPatches) {
|
|
return LoadFromEntity((entity_t*)g_FuncTable.m_pfnGetEntityHandle(id), bLoadPatches);
|
|
}
|
|
|
|
bool DEntity::LoadFromEntity(entity_t* ent, bool bLoadPatches) {
|
|
ClearPatches();
|
|
ClearBrushes();
|
|
ClearEPairs();
|
|
|
|
QER_Entity = ent;
|
|
|
|
epair_t* epl = *g_EntityTable.m_pfnGetEntityKeyValList(QER_Entity);
|
|
LoadEPairList(epl);
|
|
|
|
bool keep = FALSE;
|
|
int i;
|
|
for(i = 0; brushEntityList[i]; i++)
|
|
{
|
|
if(!stricmp(brushEntityList[i], m_Classname))
|
|
{
|
|
keep = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!keep)
|
|
return FALSE;
|
|
|
|
int count = g_FuncTable.m_pfnAllocateEntityBrushHandles(QER_Entity);
|
|
|
|
for(i = 0; i < count; i++)
|
|
{
|
|
|
|
brush_t *brush = (brush_t*)g_FuncTable.m_pfnGetEntityBrushHandle(i);
|
|
|
|
if(brush == NULL) {
|
|
DoMessageBox("GTKRadiant returned a NULL pointer, NOT a good sign", "WARNING!!!", MB_OK);
|
|
continue;
|
|
}
|
|
|
|
if(brush->pPatch)
|
|
{
|
|
if(bLoadPatches)
|
|
{
|
|
DPatch* loadPatch = NewPatch();
|
|
loadPatch->LoadFromBrush_t(brush);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBrush* loadBrush = NewBrush(i);
|
|
loadBrush->LoadFromBrush_t(brush, TRUE);
|
|
}
|
|
}
|
|
|
|
g_FuncTable.m_pfnReleaseEntityBrushHandles();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void DEntity::RemoveNonCheckBrushes(list<Str>* exclusionList, bool useDetail)
|
|
{
|
|
list<DBrush *>::iterator chkBrush=brushList.begin();
|
|
|
|
while( chkBrush!=brushList.end() )
|
|
{
|
|
if(!useDetail)
|
|
{
|
|
if((*chkBrush)->IsDetail())
|
|
{
|
|
delete *chkBrush;
|
|
chkBrush = brushList.erase(chkBrush);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
list<Str>::iterator eTexture;
|
|
|
|
for( eTexture=exclusionList->begin(); eTexture!=exclusionList->end(); eTexture++ )
|
|
{
|
|
if((*chkBrush)->HasTexture((*eTexture).GetBuffer()))
|
|
{
|
|
delete *chkBrush;
|
|
chkBrush = brushList.erase(chkBrush);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( eTexture == exclusionList->end() )
|
|
chkBrush++;
|
|
}
|
|
}
|
|
|
|
void DEntity::ResetChecks(list<Str>* exclusionList)
|
|
{
|
|
for(list<DBrush *>::const_iterator resetBrush=brushList.begin(); resetBrush!=brushList.end(); resetBrush++)
|
|
{
|
|
(*resetBrush)->ResetChecks(exclusionList);
|
|
}
|
|
}
|
|
|
|
int DEntity::FixBrushes(bool rebuild)
|
|
{
|
|
g_FuncTable.m_pfnAllocateActiveBrushHandles();
|
|
|
|
int cnt = 0;
|
|
|
|
for(list<DBrush *>::const_iterator fixBrush=brushList.begin(); fixBrush!=brushList.end(); fixBrush++)
|
|
{
|
|
int count = (*fixBrush)->RemoveRedundantPlanes();
|
|
if(count)
|
|
{
|
|
cnt += count;
|
|
if(rebuild)
|
|
{
|
|
g_FuncTable.m_pfnDeleteBrushHandle((*fixBrush)->QER_brush);
|
|
|
|
(*fixBrush)->BuildInRadiant(FALSE, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
g_FuncTable.m_pfnReleaseActiveBrushHandles();
|
|
|
|
return cnt;
|
|
}
|
|
|
|
void DEntity::BuildInRadiant(bool allowDestruction)
|
|
{
|
|
bool makeEntity = strcmp(m_Classname, "worldspawn") ? true : false;
|
|
|
|
if(makeEntity)
|
|
{
|
|
entity_t* pE = (entity_t*)g_FuncTable.m_pfnCreateEntityHandle();
|
|
|
|
epair_t* pEpS = GetNextChainItem(NULL, "classname", m_Classname);
|
|
|
|
epair_t* pEp = pEpS;
|
|
|
|
for(list<DEPair* >::const_iterator buildEPair=epairList.begin(); buildEPair!=epairList.end(); buildEPair++)
|
|
{
|
|
pEp = GetNextChainItem(pEp, (*buildEPair)->key, (*buildEPair)->value);
|
|
}
|
|
|
|
g_EntityTable.m_pfnSetEntityKeyValList(pE, pEpS);
|
|
|
|
g_FuncTable.m_pfnCommitEntityHandleToMap(pE);
|
|
|
|
for(list<DBrush *>::const_iterator buildBrush=brushList.begin(); buildBrush!=brushList.end(); buildBrush++)
|
|
(*buildBrush)->BuildInRadiant(allowDestruction, NULL, pE);
|
|
|
|
for(list<DPatch *>::const_iterator buildPatch=patchList.begin(); buildPatch!=patchList.end(); buildPatch++)
|
|
(*buildPatch)->BuildInRadiant(pE);
|
|
|
|
QER_Entity = pE;
|
|
}
|
|
else
|
|
{
|
|
for(list<DBrush *>::const_iterator buildBrush=brushList.begin(); buildBrush!=brushList.end(); buildBrush++)
|
|
(*buildBrush)->BuildInRadiant(allowDestruction, NULL);
|
|
|
|
for(list<DPatch *>::const_iterator buildPatch=patchList.begin(); buildPatch!=patchList.end(); buildPatch++)
|
|
(*buildPatch)->BuildInRadiant();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int DEntity::GetIDMax( void ) {
|
|
int max = -1;
|
|
for(list<DBrush *>::const_iterator cntBrush=brushList.begin(); cntBrush!=brushList.end(); cntBrush++) {
|
|
if((*cntBrush)->m_nBrushID > max)
|
|
max = (*cntBrush)->m_nBrushID;
|
|
}
|
|
return max+1;
|
|
}
|
|
|
|
void DEntity::SetClassname( char *classname ) {
|
|
m_Classname = classname;
|
|
}
|
|
|
|
void DEntity::SaveToFile(FILE *pFile)
|
|
{
|
|
fprintf(pFile, "{\n");
|
|
|
|
fprintf(pFile, "\"classname\" \"%s\"\n", (const char *)m_Classname);
|
|
|
|
for(list<DEPair *>::const_iterator ep=epairList.begin(); ep!=epairList.end(); ep++)
|
|
{
|
|
fprintf(pFile, "\"%s\" \"%s\"\n", (const char *)(*ep)->key, (const char *)(*ep)->value);
|
|
}
|
|
|
|
for(list<DBrush *>::const_iterator bp=brushList.begin(); bp!=brushList.end(); bp++)
|
|
{
|
|
(*bp)->SaveToFile(pFile);
|
|
}
|
|
|
|
fprintf(pFile, "}\n");
|
|
}
|
|
|
|
void DEntity::ClearEPairs()
|
|
{
|
|
for(list<DEPair *>::const_iterator deadEPair=epairList.begin(); deadEPair!=epairList.end(); deadEPair++)
|
|
{
|
|
delete (*deadEPair);
|
|
}
|
|
epairList.clear();
|
|
}
|
|
|
|
void DEntity::AddEPair(char *key, char *value) {
|
|
DEPair* newEPair;
|
|
newEPair = FindEPairByKey( key );
|
|
if(!newEPair) {
|
|
newEPair = new DEPair;
|
|
newEPair->Build(key, value);
|
|
epairList.push_back(newEPair);
|
|
} else {
|
|
newEPair->Build(key, value);
|
|
}
|
|
}
|
|
|
|
void DEntity::LoadEPairList(epair_t *epl)
|
|
{
|
|
epair_t* ep = epl;
|
|
while(ep)
|
|
{
|
|
if(!strcmp(ep->key, "classname"))
|
|
SetClassname(ep->value);
|
|
else
|
|
AddEPair(ep->key, ep->value);
|
|
|
|
ep = ep->next;
|
|
}
|
|
}
|
|
|
|
bool DEntity::ResetTextures(const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName,
|
|
int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation, bool rebuild)
|
|
{
|
|
g_FuncTable.m_pfnDeselectAllBrushes();
|
|
|
|
g_FuncTable.m_pfnAllocateActiveBrushHandles();
|
|
|
|
bool reset = FALSE;
|
|
|
|
for(list<DBrush *>::const_iterator resetBrush=brushList.begin(); resetBrush!=brushList.end(); resetBrush++)
|
|
{
|
|
bool tmp = (*resetBrush)->ResetTextures(textureName, fScale, fShift, rotation, newTextureName,
|
|
bResetTextureName, bResetScale, bResetShift, bResetRotation);
|
|
|
|
if(tmp)
|
|
{
|
|
reset = TRUE;
|
|
|
|
if(rebuild)
|
|
{
|
|
entity_t *pE = (*resetBrush)->QER_brush->owner;
|
|
g_FuncTable.m_pfnDeleteBrushHandle((*resetBrush)->QER_brush);
|
|
(*resetBrush)->BuildInRadiant(FALSE, NULL, pE->entityId == 0 ? NULL : pE);
|
|
|
|
if( pE->entityId == 0 ? NULL : pE )
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bResetTextureName)
|
|
{
|
|
for(list<DPatch *>::const_iterator resetPatch=patchList.begin(); resetPatch!=patchList.end(); resetPatch++)
|
|
{
|
|
bool tmp = (*resetPatch)->ResetTextures(textureName, newTextureName);
|
|
|
|
if(tmp)
|
|
{
|
|
reset = TRUE;
|
|
|
|
if(rebuild)
|
|
{
|
|
entity_t *pE = (*resetPatch)->QER_brush->owner;
|
|
g_FuncTable.m_pfnDeleteBrushHandle((*resetPatch)->QER_brush);
|
|
(*resetPatch)->BuildInRadiant(pE->entityId == 0 ? NULL : pE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
g_FuncTable.m_pfnReleaseActiveBrushHandles();
|
|
|
|
return reset;
|
|
}
|
|
|
|
DEPair* DEntity::FindEPairByKey(const char* keyname)
|
|
{
|
|
for(list<DEPair *>::const_iterator ep=epairList.begin(); ep!=epairList.end(); ep++)
|
|
{
|
|
char* c = (*ep)->key;
|
|
if(!strcmp(c, keyname))
|
|
return *ep;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void DEntity::RemoveFromRadiant()
|
|
{
|
|
g_EntityTable.m_pfnEntity_Free( (entity_t*)QER_Entity );
|
|
|
|
QER_Entity = NULL;
|
|
}
|
|
|
|
void DEntity::SpawnString(const char* key, const char* defaultstring, const char** out)
|
|
{
|
|
DEPair* pEP = FindEPairByKey(key);
|
|
if(pEP) {
|
|
*out = pEP->value;
|
|
} else {
|
|
*out = defaultstring;
|
|
}
|
|
}
|
|
|
|
void DEntity::SpawnInt(const char* key, const char* defaultstring, int* out)
|
|
{
|
|
DEPair* pEP = FindEPairByKey(key);
|
|
if(pEP) {
|
|
*out = atoi(pEP->value);
|
|
} else {
|
|
*out = atoi(defaultstring);
|
|
}
|
|
}
|
|
|
|
void DEntity::SpawnFloat(const char* key, const char* defaultstring, float* out)
|
|
{
|
|
DEPair* pEP = FindEPairByKey(key);
|
|
if(pEP) {
|
|
*out = static_cast< float >( atof( pEP->value ) );
|
|
} else {
|
|
*out = static_cast< float >( atof(defaultstring) );
|
|
}
|
|
}
|
|
|
|
void DEntity::SpawnVector(const char* key, const char* defaultstring, vec_t* out)
|
|
{
|
|
DEPair* pEP = FindEPairByKey(key);
|
|
if(pEP) {
|
|
sscanf(pEP->value, "%f %f %f", &out[0], &out[1], &out[2]);
|
|
} else {
|
|
sscanf(defaultstring, "%f %f %f", &out[0], &out[1], &out[2]);
|
|
}
|
|
}
|
|
|
|
int DEntity::GetBrushCount( void ) {
|
|
return brushList.size();
|
|
}
|
|
|
|
DBrush* DEntity::FindBrushByPointer( brush_t* brush ) {
|
|
for(list<DBrush *>::const_iterator listBrush = brushList.begin(); listBrush != brushList.end(); listBrush++) {
|
|
DBrush* pBrush = (*listBrush);
|
|
if(pBrush->QER_brush == brush) {
|
|
return pBrush;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|