diff --git a/libs/eclasslib.h b/libs/eclasslib.h index 43e749dc..bc1b1222 100644 --- a/libs/eclasslib.h +++ b/libs/eclasslib.h @@ -100,14 +100,19 @@ inline const char* EntityClassAttributePair_getDescription( const EntityClassAtt return EntityClassAttributePair_getName( attributePair ); } +inline bool classname_equal( const char* classname, const char* other ){ + return string_equal_nocase( classname, other ); +} + class EntityClass { -public: +private: CopiedString m_name; +public: StringList m_parent; bool fixedsize; bool unknown; // wasn't found in source -bool miscmodel_is; // definable via model attribute presence in xml .ent definition +bool miscmodel_is; // also definable via model attribute presence in xml .ent definition CopiedString m_miscmodel_key; Vector3 mins; Vector3 maxs; @@ -131,6 +136,11 @@ bool inheritanceResolved; bool sizeSpecified; bool colorSpecified; +void name_set( const char* name_ ) { + m_name = name_; + miscmodel_is = ( string_equal_prefix_nocase( name(), "misc_" ) && string_equal_suffix_nocase( name(), "model" ) ) // misc_*model (also misc_model) + || classname_equal( name(), "model_static" ); +} const char* name() const { return m_name.c_str(); } @@ -164,17 +174,6 @@ inline EntityClassAttributePair& EntityClass_insertAttribute( EntityClass& entit } -inline bool classname_equal( const char* classname, const char* other ){ - return string_equal_nocase( classname, other ); -} - -inline bool EntityClass_miscmodel_is( const EntityClass* entityClass ){ - return entityClass->miscmodel_is - || ( string_compare_nocase_n( entityClass->name(), "misc_", 5 ) == 0 && string_equal_nocase( entityClass->name() + string_length( entityClass->name() ) - 5, "model" ) ) // misc_*model (also misc_model) - || classname_equal( entityClass->name(), "model_static" ); -} - - inline void buffer_write_colour_add( char buffer[128], const Colour3& colour ){ sprintf( buffer, "{%g %g %g}", colour[0], colour[1], colour[2] ); } @@ -284,7 +283,7 @@ inline EntityClass* EClass_Create( const char* name, const Vector3& colour, cons EntityClass *e = Eclass_Alloc(); e->free = &Eclass_Free; - e->m_name = name; + e->name_set( name ); e->color = colour; eclass_capture_state( e ); @@ -300,7 +299,7 @@ inline EntityClass* EClass_Create_FixedSize( const char* name, const Vector3& co EntityClass *e = Eclass_Alloc(); e->free = &Eclass_Free; - e->m_name = name; + e->name_set( name ); e->color = colour; eclass_capture_state( e ); diff --git a/plugins/entity/entity.cpp b/plugins/entity/entity.cpp index 42ce2908..a994c3f0 100644 --- a/plugins/entity/entity.cpp +++ b/plugins/entity/entity.cpp @@ -51,7 +51,7 @@ EGameType g_gameType; inline scene::Node& entity_for_eclass( EntityClass* eclass ){ - if ( EntityClass_miscmodel_is( eclass ) ) { + if ( eclass->miscmodel_is ) { return New_MiscModel( eclass ); } else if ( classname_equal( eclass->name(), "light" ) @@ -348,11 +348,18 @@ bool filter( const Entity& entity ) const { filter_entity_classname g_filter_entity_func_group( "func_group" ); filter_entity_classgroup g_filter_entity_func_detail( "func_detail" ); filter_entity_classname g_filter_entity_light( "light" ); -filter_entity_classname g_filter_entity_misc_model( "misc_model" ); -filter_entity_classname g_filter_entity_misc_gamemodel( "misc_gamemodel" ); filter_entity_classgroup g_filter_entity_trigger( "trigger_" ); filter_entity_classgroup g_filter_entity_path( "path_" ); +class filter_entity_misc_model : public EntityFilter +{ +public: +bool filter( const Entity& entity ) const { + return entity.getEntityClass().miscmodel_is; +} +}; +filter_entity_misc_model g_filter_entity_misc_model; + class filter_entity_doom3model : public EntityFilter { public: @@ -388,7 +395,6 @@ void Entity_InitFilters(){ add_entity_filter( g_filter_entity_world, EXCLUDE_ENT, true ); add_entity_filter( g_filter_entity_trigger, EXCLUDE_TRIGGERS ); add_entity_filter( g_filter_entity_misc_model, EXCLUDE_MODELS ); - add_entity_filter( g_filter_entity_misc_gamemodel, EXCLUDE_MODELS ); add_entity_filter( g_filter_entity_doom3model, EXCLUDE_MODELS ); add_entity_filter( g_filter_entity_light, EXCLUDE_LIGHTS ); add_entity_filter( g_filter_entity_path, EXCLUDE_PATHS ); diff --git a/radiant/eclass_def.cpp b/radiant/eclass_def.cpp index 8637b480..055757ed 100644 --- a/radiant/eclass_def.cpp +++ b/radiant/eclass_def.cpp @@ -204,7 +204,7 @@ EntityClass *Eclass_InitFromText( const char *text ){ // grab the name text = COM_Parse( text ); - e->m_name = Get_COM_Token(); + e->name_set( Get_COM_Token() ); debugname = e->name(); { diff --git a/radiant/eclass_doom3.cpp b/radiant/eclass_doom3.cpp index a358dcce..91215d8f 100644 --- a/radiant/eclass_doom3.cpp +++ b/radiant/eclass_doom3.cpp @@ -313,7 +313,9 @@ inline const char* string_findFirstNonSpaceOrTab( const char* string ){ static bool EntityClass_parse( EntityClass& entityClass, Tokeniser& tokeniser ){ - PARSE_RETURN_FALSE_IF_FAIL( EntityClassDoom3_parseString( tokeniser, entityClass.m_name ) ); + const char* name; + PARSE_RETURN_FALSE_IF_FAIL( EntityClassDoom3_parseString( tokeniser, name ) ); + entityClass.name_set( name ); PARSE_RETURN_FALSE_IF_FAIL( EntityClassDoom3_parseToken( tokeniser, "{" ) ); tokeniser.nextLine(); @@ -512,7 +514,7 @@ static bool EntityClass_parse( EntityClass& entityClass, Tokeniser& tokeniser ){ const char* value; PARSE_RETURN_FALSE_IF_FAIL( EntityClassDoom3_parseString( tokeniser, value ) ); if ( string_equal( value, "}" ) ) { // hack for quake4 powerups.def bug - globalErrorStream() << "entityDef " << makeQuoted( entityClass.m_name.c_str() ) << " key " << makeQuoted( tmp.c_str() ) << " has no value\n"; + globalErrorStream() << "entityDef " << makeQuoted( entityClass.name() ) << " key " << makeQuoted( tmp.c_str() ) << " has no value\n"; break; } else @@ -525,7 +527,7 @@ static bool EntityClass_parse( EntityClass& entityClass, Tokeniser& tokeniser ){ entityClass.m_comments = usage.c_str(); - if ( string_equal( entityClass.m_name.c_str(), "light" ) ) { + if ( string_equal( entityClass.name(), "light" ) ) { { EntityClassAttribute& attribute = EntityClass_insertAttribute( entityClass, "light_radius" ).second; attribute.m_type = "vector3"; @@ -656,7 +658,7 @@ void EntityClass_resolveInheritance( EntityClass* derivedClass ){ derivedClass->inheritanceResolved = true; EntityClasses::iterator i = g_EntityClassDoom3_classes.find( derivedClass->m_parent.front().c_str() ); if ( i == g_EntityClassDoom3_classes.end() ) { - globalErrorStream() << "failed to find entityDef " << makeQuoted( derivedClass->m_parent.front().c_str() ) << " inherited by " << makeQuoted( derivedClass->m_name.c_str() ) << "\n"; + globalErrorStream() << "failed to find entityDef " << makeQuoted( derivedClass->m_parent.front().c_str() ) << " inherited by " << makeQuoted( derivedClass->name() ) << "\n"; } else { diff --git a/radiant/eclass_fgd.cpp b/radiant/eclass_fgd.cpp index 7b877915..330ee5a9 100644 --- a/radiant/eclass_fgd.cpp +++ b/radiant/eclass_fgd.cpp @@ -233,7 +233,7 @@ void EntityClassFGD_parseClass( Tokeniser& tokeniser, bool fixedsize, bool isBas } } - entityClass->m_name = tokeniser.getToken(); + entityClass->name_set( tokeniser.getToken() ); if ( !isBase ) { ASSERT_MESSAGE( EntityClassFGD_parseToken( tokeniser, ":" ), PARSE_ERROR ); @@ -361,7 +361,7 @@ void EntityClassFGD_parseClass( Tokeniser& tokeniser, bool fixedsize, bool isBas tokeniser.nextLine(); StringOutputStream listTypeName( 64 ); - listTypeName << entityClass->m_name.c_str() << "_" << attribute.m_name.c_str(); + listTypeName << entityClass->name() << "_" << attribute.m_name.c_str(); attribute.m_type = listTypeName.c_str(); ListAttributeType& listType = g_listTypesFGD[listTypeName.c_str()]; @@ -572,7 +572,7 @@ void EntityClassFGD_resolveInheritance( EntityClass* derivedClass ){ { BaseClasses::iterator i = g_EntityClassFGD_bases.find( ( *j ).c_str() ); if ( i == g_EntityClassFGD_bases.end() ) { - globalErrorStream() << "failed to find entityDef " << makeQuoted( ( *j ).c_str() ) << " inherited by " << makeQuoted( derivedClass->m_name.c_str() ) << "\n"; + globalErrorStream() << "failed to find entityDef " << makeQuoted( ( *j ).c_str() ) << " inherited by " << makeQuoted( derivedClass->name() ) << "\n"; } else { @@ -616,10 +616,10 @@ void realise(){ EntityClassFGD_resolveInheritance( ( *i ).second ); if ( ( *i ).second->fixedsize && string_empty( ( *i ).second->m_modelpath.c_str() ) ) { if ( !( *i ).second->sizeSpecified ) { - globalErrorStream() << "size not specified for entity class: " << makeQuoted( ( *i ).second->m_name.c_str() ) << '\n'; + globalErrorStream() << "size not specified for entity class: " << makeQuoted( ( *i ).second->name() ) << '\n'; } if ( !( *i ).second->colorSpecified ) { - globalErrorStream() << "color not specified for entity class: " << makeQuoted( ( *i ).second->m_name.c_str() ) << '\n'; + globalErrorStream() << "color not specified for entity class: " << makeQuoted( ( *i ).second->name() ) << '\n'; } } } diff --git a/radiant/eclass_xml.cpp b/radiant/eclass_xml.cpp index 8fb44d25..60f8435c 100644 --- a/radiant/eclass_xml.cpp +++ b/radiant/eclass_xml.cpp @@ -276,7 +276,7 @@ ClassImporter( EntityClassCollector& collector, ListAttributeTypes& listTypes, c const char* name = element.attribute( "name" ); ASSERT_MESSAGE( !string_empty( name ), "name attribute not specified for class" ); - m_eclass->m_name = name; + m_eclass->name_set( name ); const char* color = element.attribute( "color" ); ASSERT_MESSAGE( !string_empty( name ), "color attribute not specified for class " << name ); diff --git a/radiant/entity.cpp b/radiant/entity.cpp index f782f6b3..784cd762 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -369,10 +369,10 @@ void Entity_createFromSelection( const char* name, const Vector3& origin ){ EntityClass* entityClass = GlobalEntityClassManager().findOrInsert( name, true ); - const bool isModel = EntityClass_miscmodel_is( entityClass ) + const bool isModel = entityClass->miscmodel_is || ( GlobalSelectionSystem().countSelected() == 0 && classname_equal( name, "func_static" ) && g_pGameDescription->mGameType == "doom3" ); - bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0; + const bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0; //is important to have retexturing here; if doing in the end, undo doesn't succeed; if ( string_compare_nocase_n( name, "trigger_", 8 ) == 0 && brushesSelected && !entityClass->fixedsize ){