etqw-sdk/source/game/decls/DeclTargetInfo.cpp

235 lines
5 KiB
C++
Raw Normal View History

2008-05-29 00:00:00 +00:00
// 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() ];
}
}
}