refactored EntityClass usage to only store being a miscmodel in miscmodel_is bool + set it on setting classname

* miscmodel filter: simplify and support miscmodels, defined by new way (xml .ent)
This commit is contained in:
Garux 2018-02-19 00:40:51 +03:00
parent feedf4919e
commit 1b673b1a76
7 changed files with 39 additions and 32 deletions

View File

@ -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 );

View File

@ -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 );

View File

@ -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();
{

View File

@ -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
{

View File

@ -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';
}
}
}

View File

@ -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 );

View File

@ -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 ){