2007-11-04 03:51:54 +00:00
|
|
|
/*
|
2012-03-17 20:01:54 +00:00
|
|
|
BobToolz plugin for GtkRadiant
|
|
|
|
Copyright (C) 2001 Gordon Biggans
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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.
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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.
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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
|
|
|
|
*/
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
// DEntity.cpp: implementation of the DEntity class.
|
|
|
|
//
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "StdAfx.h"
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#pragma warning(disable : 4786)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "DEntity.h"
|
|
|
|
|
2008-02-18 20:54:58 +00:00
|
|
|
#include "dialogs/dialogs-gtk.h"
|
2007-11-04 03:51:54 +00:00
|
|
|
#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
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
DEntity::DEntity( char *classname, int ID ){
|
|
|
|
SetClassname( classname );
|
2007-11-04 03:51:54 +00:00
|
|
|
m_nID = ID;
|
|
|
|
QER_Entity = NULL;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
DEntity::~DEntity(){
|
2007-11-04 03:51:54 +00:00
|
|
|
ClearPatches();
|
|
|
|
ClearBrushes();
|
|
|
|
ClearEPairs();
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Implementation
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::ClearBrushes(){
|
|
|
|
for ( list<DBrush *>::const_iterator deadBrush = brushList.begin(); deadBrush != brushList.end(); deadBrush++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
|
|
|
delete *deadBrush;
|
|
|
|
}
|
|
|
|
brushList.clear();
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::ClearPatches(){
|
|
|
|
for ( list<DPatch *>::const_iterator deadPatch = patchList.begin(); deadPatch != patchList.end(); deadPatch++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
|
|
|
delete *deadPatch;
|
|
|
|
}
|
|
|
|
patchList.clear();
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
DPatch* DEntity::NewPatch(){
|
2007-11-04 03:51:54 +00:00
|
|
|
DPatch* newPatch = new DPatch;
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
patchList.push_back( newPatch );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
return newPatch;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
DBrush* DEntity::NewBrush( int ID ){
|
|
|
|
DBrush* newBrush = new DBrush( ID );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
brushList.push_back( newBrush );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
return newBrush;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
char* getNextBracket( char* s ){
|
2007-11-04 03:51:54 +00:00
|
|
|
char* p = s;
|
2012-03-17 20:01:54 +00:00
|
|
|
while ( *p )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
|
|
|
p++;
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( *p == '(' ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
break;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
bool DEntity::LoadFromPrt( char *filename ){
|
2007-11-04 03:51:54 +00:00
|
|
|
CPortals portals;
|
2012-03-17 20:01:54 +00:00
|
|
|
strcpy( portals.fn, filename );
|
2007-11-04 03:51:54 +00:00
|
|
|
portals.Load();
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( portals.node_count == 0 ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return FALSE;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
ClearBrushes();
|
|
|
|
ClearEPairs();
|
2008-09-06 08:35:17 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
bool build = false;
|
|
|
|
for ( unsigned int i = 0; i < portals.node_count; i++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
build = false;
|
2007-11-04 03:51:54 +00:00
|
|
|
DBrush* brush = NewBrush();
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( unsigned int j = 0; j < portals.node[i].portal_count; j++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
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 );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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 );
|
2007-11-04 03:51:54 +00:00
|
|
|
// slow, dont use much
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
DBrush* DEntity::GetBrushForID( int ID ){
|
2007-11-04 03:51:54 +00:00
|
|
|
DBrush* buildBrush = NULL;
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator chkBrush = brushList.begin(); chkBrush != brushList.end(); chkBrush++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( ( *chkBrush )->m_nBrushID == ID ) {
|
|
|
|
buildBrush = ( *chkBrush );
|
2007-11-04 03:51:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !buildBrush ) {
|
|
|
|
buildBrush = NewBrush( ID );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
return buildBrush;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::LoadSelectedBrushes(){
|
2007-11-04 03:51:54 +00:00
|
|
|
ClearBrushes();
|
|
|
|
ClearEPairs();
|
|
|
|
|
|
|
|
int count = g_FuncTable.m_pfnAllocateSelectedBrushHandles();
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( int i = 0; i < count; i++ ) {
|
|
|
|
brush_t *brush = (brush_t*)g_FuncTable.m_pfnGetSelectedBrushHandle( i );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( brush->pPatch ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
continue;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
DBrush* loadBrush = NewBrush( i );
|
|
|
|
loadBrush->LoadFromBrush_t( brush, TRUE );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_FuncTable.m_pfnReleaseSelectedBrushHandles();
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::LoadSelectedPatches(){
|
2007-11-04 03:51:54 +00:00
|
|
|
ClearPatches();
|
|
|
|
ClearEPairs();
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
int count = g_FuncTable.m_pfnAllocateSelectedPatchHandles();
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( int i = 0; i < count; i++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
//$ FIXME: m_pfnGetPatchHandle
|
|
|
|
patchMesh_t *pmesh = (patchMesh_t*)g_FuncTable.m_pfnGetPatchData( i );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
DPatch* loadPatch = NewPatch();
|
2012-03-17 20:01:54 +00:00
|
|
|
loadPatch->LoadFromBrush_t( pmesh->pSymbiot );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
g_FuncTable.m_pfnReleasePatchHandles();
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
bool* DEntity::BuildIntersectList(){
|
2007-11-04 03:51:54 +00:00
|
|
|
int max = GetIDMax();
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( max == 0 ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return NULL;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
bool* pbIntList = new bool[max];
|
2012-03-17 20:01:54 +00:00
|
|
|
memset( pbIntList, 0, sizeof( bool ) * ( max ) );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator pB1 = brushList.begin(); pB1 != brushList.end(); pB1++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
list<DBrush *>::const_iterator pB2 = pB1;
|
|
|
|
for ( pB2++; pB2 != brushList.end(); pB2++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( ( *pB1 )->IntersectsWith( ( *pB2 ) ) ) {
|
|
|
|
pbIntList[( *pB1 )->m_nBrushID] = TRUE;
|
|
|
|
pbIntList[( *pB2 )->m_nBrushID] = TRUE;
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pbIntList;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
bool* DEntity::BuildDuplicateList(){
|
2007-11-04 03:51:54 +00:00
|
|
|
int max = GetIDMax();
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( max == 0 ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return NULL;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
bool* pbDupList = new bool[max];
|
2012-03-17 20:01:54 +00:00
|
|
|
memset( pbDupList, 0, sizeof( bool ) * ( max ) );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator pB1 = brushList.begin(); pB1 != brushList.end(); pB1++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
list<DBrush *>::const_iterator pB2 = pB1;
|
|
|
|
for ( pB2++; pB2 != brushList.end(); pB2++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( **pB1 == *pB2 ) {
|
|
|
|
pbDupList[( *pB1 )->m_nBrushID] = TRUE;
|
|
|
|
pbDupList[( *pB2 )->m_nBrushID] = TRUE;
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pbDupList;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::SelectBrushes( bool *selectList ){
|
|
|
|
if ( selectList == NULL ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
g_FuncTable.m_pfnDeselectAllBrushes();
|
|
|
|
|
|
|
|
g_FuncTable.m_pfnAllocateActiveBrushHandles();
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator pBrush = brushList.begin(); pBrush != brushList.end(); pBrush++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( selectList[( *pBrush )->m_nBrushID] ) {
|
|
|
|
g_FuncTable.m_pfnSelectBrush( ( *pBrush )->QER_brush );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
g_FuncTable.m_pfnReleaseActiveBrushHandles();
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
bool DEntity::LoadFromEntity( int id, bool bLoadPatches ) {
|
|
|
|
return LoadFromEntity( (entity_t*)g_FuncTable.m_pfnGetEntityHandle( id ), bLoadPatches );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
bool DEntity::LoadFromEntity( entity_t* ent, bool bLoadPatches ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
ClearPatches();
|
|
|
|
ClearBrushes();
|
|
|
|
ClearEPairs();
|
|
|
|
|
|
|
|
QER_Entity = ent;
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
epair_t* epl = *g_EntityTable.m_pfnGetEntityKeyValList( QER_Entity );
|
|
|
|
LoadEPairList( epl );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
bool keep = FALSE;
|
|
|
|
int i;
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( i = 0; brushEntityList[i]; i++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !stricmp( brushEntityList[i], m_Classname ) ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
keep = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !keep ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return FALSE;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
int count = g_FuncTable.m_pfnAllocateEntityBrushHandles( QER_Entity );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( i = 0; i < count; i++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
brush_t *brush = (brush_t*)g_FuncTable.m_pfnGetEntityBrushHandle( i );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( brush == NULL ) {
|
|
|
|
DoMessageBox( "GTKRadiant returned a NULL pointer, NOT a good sign", "WARNING!!!", MB_OK );
|
|
|
|
continue;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( brush->pPatch ) {
|
|
|
|
if ( bLoadPatches ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
DPatch* loadPatch = NewPatch();
|
2012-03-17 20:01:54 +00:00
|
|
|
loadPatch->LoadFromBrush_t( brush );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
DBrush* loadBrush = NewBrush( i );
|
|
|
|
loadBrush->LoadFromBrush_t( brush, TRUE );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_FuncTable.m_pfnReleaseEntityBrushHandles();
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::RemoveNonCheckBrushes( list<Str>* exclusionList, bool useDetail ){
|
|
|
|
list<DBrush *>::iterator chkBrush = brushList.begin();
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
while ( chkBrush != brushList.end() )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !useDetail ) {
|
|
|
|
if ( ( *chkBrush )->IsDetail() ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
delete *chkBrush;
|
2012-03-17 20:01:54 +00:00
|
|
|
chkBrush = brushList.erase( chkBrush );
|
2007-11-04 03:51:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
list<Str>::iterator eTexture;
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( eTexture = exclusionList->begin(); eTexture != exclusionList->end(); eTexture++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( ( *chkBrush )->HasTexture( ( *eTexture ).GetBuffer() ) ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
delete *chkBrush;
|
2012-03-17 20:01:54 +00:00
|
|
|
chkBrush = brushList.erase( chkBrush );
|
2007-11-04 03:51:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( eTexture == exclusionList->end() ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
chkBrush++;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::ResetChecks( list<Str>* exclusionList ){
|
|
|
|
for ( list<DBrush *>::const_iterator resetBrush = brushList.begin(); resetBrush != brushList.end(); resetBrush++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
( *resetBrush )->ResetChecks( exclusionList );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
int DEntity::FixBrushes( bool rebuild ){
|
2007-11-04 03:51:54 +00:00
|
|
|
g_FuncTable.m_pfnAllocateActiveBrushHandles();
|
|
|
|
|
|
|
|
int cnt = 0;
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator fixBrush = brushList.begin(); fixBrush != brushList.end(); fixBrush++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
int count = ( *fixBrush )->RemoveRedundantPlanes();
|
|
|
|
if ( count ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
cnt += count;
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( rebuild ) {
|
|
|
|
g_FuncTable.m_pfnDeleteBrushHandle( ( *fixBrush )->QER_brush );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
( *fixBrush )->BuildInRadiant( FALSE, NULL );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_FuncTable.m_pfnReleaseActiveBrushHandles();
|
|
|
|
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::BuildInRadiant( bool allowDestruction ){
|
|
|
|
bool makeEntity = strcmp( m_Classname, "worldspawn" ) ? true : false;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( makeEntity ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
entity_t* pE = (entity_t*)g_FuncTable.m_pfnCreateEntityHandle();
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
epair_t* pEpS = GetNextChainItem( NULL, "classname", m_Classname );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
epair_t* pEp = pEpS;
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DEPair* >::const_iterator buildEPair = epairList.begin(); buildEPair != epairList.end(); buildEPair++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
pEp = GetNextChainItem( pEp, ( *buildEPair )->key, ( *buildEPair )->value );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
g_EntityTable.m_pfnSetEntityKeyValList( pE, pEpS );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
g_FuncTable.m_pfnCommitEntityHandleToMap( pE );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator buildBrush = brushList.begin(); buildBrush != brushList.end(); buildBrush++ )
|
|
|
|
( *buildBrush )->BuildInRadiant( allowDestruction, NULL, pE );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DPatch *>::const_iterator buildPatch = patchList.begin(); buildPatch != patchList.end(); buildPatch++ )
|
|
|
|
( *buildPatch )->BuildInRadiant( pE );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
QER_Entity = pE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator buildBrush = brushList.begin(); buildBrush != brushList.end(); buildBrush++ )
|
|
|
|
( *buildBrush )->BuildInRadiant( allowDestruction, NULL );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DPatch *>::const_iterator buildPatch = patchList.begin(); buildPatch != patchList.end(); buildPatch++ )
|
|
|
|
( *buildPatch )->BuildInRadiant();
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int DEntity::GetIDMax( void ) {
|
|
|
|
int max = -1;
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator cntBrush = brushList.begin(); cntBrush != brushList.end(); cntBrush++ ) {
|
|
|
|
if ( ( *cntBrush )->m_nBrushID > max ) {
|
|
|
|
max = ( *cntBrush )->m_nBrushID;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
2012-03-17 20:01:54 +00:00
|
|
|
return max + 1;
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DEntity::SetClassname( char *classname ) {
|
|
|
|
m_Classname = classname;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::SaveToFile( FILE *pFile ){
|
|
|
|
fprintf( pFile, "{\n" );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
fprintf( pFile, "\"classname\" \"%s\"\n", (const char *)m_Classname );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DEPair *>::const_iterator ep = epairList.begin(); ep != epairList.end(); ep++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
fprintf( pFile, "\"%s\" \"%s\"\n", (const char *)( *ep )->key, (const char *)( *ep )->value );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator bp = brushList.begin(); bp != brushList.end(); bp++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
( *bp )->SaveToFile( pFile );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
fprintf( pFile, "}\n" );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::ClearEPairs(){
|
|
|
|
for ( list<DEPair *>::const_iterator deadEPair = epairList.begin(); deadEPair != epairList.end(); deadEPair++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
delete ( *deadEPair );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
epairList.clear();
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::AddEPair( const char *key, const char *value ) {
|
2008-09-06 08:35:17 +00:00
|
|
|
DEPair* newEPair;
|
2007-11-04 03:51:54 +00:00
|
|
|
newEPair = FindEPairByKey( key );
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !newEPair ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
newEPair = new DEPair;
|
2012-03-17 20:01:54 +00:00
|
|
|
newEPair->Build( key, value );
|
|
|
|
epairList.push_back( newEPair );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
newEPair->Build( key, value );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::LoadEPairList( epair_t *epl ){
|
2007-11-04 03:51:54 +00:00
|
|
|
epair_t* ep = epl;
|
2012-03-17 20:01:54 +00:00
|
|
|
while ( ep )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !strcmp( ep->key, "classname" ) ) {
|
|
|
|
SetClassname( ep->value );
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
AddEPair( ep->key, ep->value );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
ep = ep->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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 ){
|
2007-11-04 03:51:54 +00:00
|
|
|
g_FuncTable.m_pfnDeselectAllBrushes();
|
|
|
|
|
|
|
|
g_FuncTable.m_pfnAllocateActiveBrushHandles();
|
|
|
|
|
|
|
|
bool reset = FALSE;
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator resetBrush = brushList.begin(); resetBrush != brushList.end(); resetBrush++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
bool tmp = ( *resetBrush )->ResetTextures( textureName, fScale, fShift, rotation, newTextureName,
|
|
|
|
bResetTextureName, bResetScale, bResetShift, bResetRotation );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( tmp ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
reset = TRUE;
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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 );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( pE->entityId == 0 ? NULL : pE ) {
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( bResetTextureName ) {
|
|
|
|
for ( list<DPatch *>::const_iterator resetPatch = patchList.begin(); resetPatch != patchList.end(); resetPatch++ )
|
|
|
|
{
|
|
|
|
bool tmp = ( *resetPatch )->ResetTextures( textureName, newTextureName );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( tmp ) {
|
|
|
|
reset = TRUE;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( rebuild ) {
|
|
|
|
entity_t *pE = ( *resetPatch )->QER_brush->owner;
|
|
|
|
g_FuncTable.m_pfnDeleteBrushHandle( ( *resetPatch )->QER_brush );
|
|
|
|
( *resetPatch )->BuildInRadiant( pE->entityId == 0 ? NULL : pE );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
g_FuncTable.m_pfnReleaseActiveBrushHandles();
|
|
|
|
|
|
|
|
return reset;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
DEPair* DEntity::FindEPairByKey( const char* keyname ){
|
|
|
|
for ( list<DEPair *>::const_iterator ep = epairList.begin(); ep != epairList.end(); ep++ )
|
2007-11-04 03:51:54 +00:00
|
|
|
{
|
2012-03-17 20:01:54 +00:00
|
|
|
char* c = ( *ep )->key;
|
|
|
|
if ( !strcmp( c, keyname ) ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return *ep;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::RemoveFromRadiant(){
|
2007-11-04 03:51:54 +00:00
|
|
|
g_EntityTable.m_pfnEntity_Free( (entity_t*)QER_Entity );
|
|
|
|
|
|
|
|
QER_Entity = NULL;
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::SpawnString( const char* key, const char* defaultstring, const char** out ){
|
|
|
|
DEPair* pEP = FindEPairByKey( key );
|
|
|
|
if ( pEP ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
*out = pEP->value;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
|
|
|
else {
|
2007-11-04 03:51:54 +00:00
|
|
|
*out = defaultstring;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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 );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void DEntity::SpawnFloat( const char* key, const char* defaultstring, float* out ){
|
|
|
|
DEPair* pEP = FindEPairByKey( key );
|
|
|
|
if ( pEP ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
*out = static_cast< float >( atof( pEP->value ) );
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
*out = static_cast< float >( atof( defaultstring ) );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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] );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int DEntity::GetBrushCount( void ) {
|
|
|
|
return brushList.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
DBrush* DEntity::FindBrushByPointer( brush_t* brush ) {
|
2012-03-17 20:01:54 +00:00
|
|
|
for ( list<DBrush *>::const_iterator listBrush = brushList.begin(); listBrush != brushList.end(); listBrush++ ) {
|
|
|
|
DBrush* pBrush = ( *listBrush );
|
|
|
|
if ( pBrush->QER_brush == brush ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return pBrush;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|