234 lines
5 KiB
C++
234 lines
5 KiB
C++
// Copyright (C) 2007 Id Software, Inc.
|
|
//
|
|
|
|
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "DeclTargetInfo.h"
|
|
#include "../gamesys/Class.h"
|
|
#include "../../decllib/declEntityDef.h"
|
|
#include "../Entity.h"
|
|
#include "../../framework/DeclParseHelper.h"
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
sdDeclTargetInfo
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*
|
|
================
|
|
sdDeclTargetInfo::sdDeclTargetInfo
|
|
================
|
|
*/
|
|
sdDeclTargetInfo::sdDeclTargetInfo( void ) {
|
|
}
|
|
|
|
/*
|
|
================
|
|
sdDeclTargetInfo::~sdDeclTargetInfo
|
|
================
|
|
*/
|
|
sdDeclTargetInfo::~sdDeclTargetInfo( void ) {
|
|
}
|
|
|
|
/*
|
|
================
|
|
sdDeclTargetInfo::DefaultDefinition
|
|
================
|
|
*/
|
|
const char* sdDeclTargetInfo::DefaultDefinition( void ) const {
|
|
return \
|
|
"{\n" \
|
|
"}\n";
|
|
}
|
|
|
|
/*
|
|
================
|
|
sdDeclTargetInfo::ParseType
|
|
================
|
|
*/
|
|
bool sdDeclTargetInfo::ParseType( idParser& src, bool include ) {
|
|
idToken token;
|
|
|
|
if ( !src.ReadToken( &token ) ) {
|
|
return false;
|
|
}
|
|
|
|
targetInfo_t info;
|
|
info.include = include;
|
|
|
|
if ( !token.Icmp( "class" ) ) {
|
|
|
|
info.type = TI_CLASS;
|
|
|
|
if( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
|
|
return false;
|
|
}
|
|
|
|
idTypeInfo* type = idClass::GetClass( token );
|
|
if ( !type ) {
|
|
src.Warning( "sdDeclTargetInfo::ParseType Unknown Class '%s'", token.c_str() );
|
|
return false;
|
|
}
|
|
|
|
info.index = type->typeNum;
|
|
|
|
} else if ( !token.Icmp( "reference" ) ) {
|
|
|
|
info.type = TI_REFERENCE;
|
|
|
|
if( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
|
|
return false;
|
|
}
|
|
|
|
const sdDeclTargetInfo* decl = gameLocal.declTargetInfoType[ token ];
|
|
if ( !decl ) {
|
|
src.Warning( "sdDeclTargetInfo::ParseType Reference '%s'", token.c_str() );
|
|
return false;
|
|
}
|
|
|
|
info.index = decl->Index();
|
|
|
|
} else if ( !token.Icmp( "collection" ) ) {
|
|
|
|
info.type = TI_COLLECTION;
|
|
|
|
if( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
|
|
return false;
|
|
}
|
|
|
|
info.collection = gameLocal.GetEntityCollection( token, true );
|
|
|
|
} else {
|
|
src.Warning( "sdDeclTargetInfo::ParseType Invalid Include/Exclude Type '%s'", token.c_str() );
|
|
return false;
|
|
}
|
|
|
|
filters.Alloc() = info;
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
================
|
|
sdDeclTargetInfo::Parse
|
|
================
|
|
*/
|
|
bool sdDeclTargetInfo::Parse( const char *text, const int textLength ) {
|
|
idToken token;
|
|
idParser src;
|
|
|
|
src.SetFlags( DECL_LEXER_FLAGS );
|
|
//src.LoadMemory( text, textLength, GetFileName(), GetLineNum() );
|
|
sdDeclParseHelper declHelper( this, text, textLength, src );
|
|
|
|
src.SkipUntilString( "{", &token );
|
|
|
|
while( true ) {
|
|
if ( !src.ReadToken( &token ) ) {
|
|
src.Warning( "sdDeclTargetInfo::Parse Unexpected end of file" );
|
|
return false;
|
|
}
|
|
|
|
if ( !token.Cmp( "}" ) ) {
|
|
break;
|
|
}
|
|
|
|
if ( !token.Icmp( "include" ) ) {
|
|
if ( !ParseType( src, true ) ) {
|
|
src.Warning( "sdDeclTargetInfo::Parse Failure Parsing Type '%s'", token.c_str() );
|
|
return false;
|
|
}
|
|
} else if ( !token.Icmp( "exclude" ) ) {
|
|
if ( !ParseType( src, false ) ) {
|
|
src.Warning( "sdDeclTargetInfo::Parse Failure Parsing Type '%s'", token.c_str() );
|
|
return false;
|
|
}
|
|
} else if ( !token.Icmp( "require" ) ) {
|
|
if ( !src.ReadToken( &token ) ) {
|
|
src.Warning( "sdDeclTargetInfo::Parse Failure Parsing Requirement" );
|
|
return false;
|
|
}
|
|
|
|
requirements.Load( token.c_str() );
|
|
} else {
|
|
src.Warning( "sdDeclTargetInfo::Parse Unknown token '%s'", token.c_str() );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
================
|
|
sdDeclTargetInfo::FreeData
|
|
================
|
|
*/
|
|
void sdDeclTargetInfo::FreeData( void ) {
|
|
filters.Clear();
|
|
}
|
|
|
|
/*
|
|
================
|
|
sdDeclTargetInfo::FilterEntity
|
|
================
|
|
*/
|
|
bool sdDeclTargetInfo::FilterEntity( idEntity* entity ) const {
|
|
if ( !entity ) {
|
|
assert( false );
|
|
return false;
|
|
}
|
|
|
|
bool keep = false;
|
|
|
|
int i;
|
|
for ( i = 0; i < filters.Num(); i++ ) {
|
|
const targetInfo_t& targetInfo = filters[ i ];
|
|
|
|
switch( targetInfo.type ) {
|
|
case TI_CLASS: {
|
|
idTypeInfo* type = idClass::GetType( targetInfo.index );
|
|
if ( entity->IsType( *type ) ) {
|
|
keep = targetInfo.include;
|
|
}
|
|
break;
|
|
}
|
|
case TI_REFERENCE: {
|
|
const sdDeclTargetInfo *reference = gameLocal.declTargetInfoType[ targetInfo.index ];
|
|
keep = (targetInfo.include == reference->FilterEntity( entity ));
|
|
break;
|
|
}
|
|
case TI_COLLECTION: {
|
|
if ( targetInfo.collection->Contains( entity ) ) {
|
|
keep = targetInfo.include;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( keep ) {
|
|
keep = requirements.Check( entity );
|
|
}
|
|
|
|
return keep;
|
|
}
|
|
|
|
/*
|
|
================
|
|
sdDeclTargetInfo::CacheFromDict
|
|
================
|
|
*/
|
|
void sdDeclTargetInfo::CacheFromDict( const idDict& dict ) {
|
|
const idKeyValue* kv = NULL;
|
|
|
|
while( kv = dict.MatchPrefix( "ti_", kv ) ) {
|
|
if ( kv->GetValue().Length() ) {
|
|
gameLocal.declTargetInfoType[ kv->GetValue() ];
|
|
}
|
|
}
|
|
}
|