etqw-sdk/source/game/roles/RoleManager.cpp
2008-05-29 00:00:00 +00:00

384 lines
8.7 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#include "../precompiled.h"
#pragma hdrstop
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "RoleManager.h"
#include "../structures/TeamManager.h"
/*
===============================================================================
sdRequirementCondition
===============================================================================
*/
/*
================
sdRequirementCondition::sdRequirementCondition
================
*/
sdRequirementCondition::sdRequirementCondition( const char* requirement ) {
idLexer parser( requirement, idStr::Length( requirement ), "sdRequirementCondition::sdRequirementCondition" );
valueRegister = ParseExpression( &parser );
}
/*
================
sdRequirementCondition::ExpressionOp
================
*/
sdRequirementCondition::rexpOp_t& sdRequirementCondition::ExpressionOp( void ) {
rexpOp_t& wop = ops.Alloc();
memset( &wop, 0, sizeof( wop ) );
return wop;
}
/*
================
sdRequirementCondition::ExpressionTemporary
================
*/
int sdRequirementCondition::ExpressionTemporary( void ) {
int i = registers.Num();
expressionRegister_t& r = registers.Alloc();
r.temporary = true;
r.value = false;
return i;
}
/*
================
sdRequirementCondition::EmitOp
================
*/
int sdRequirementCondition::EmitOp( int a, int b, rexpOpType_t opType, rexpOp_t** opp ) {
rexpOp_t& op = ExpressionOp();
op.opType = opType;
op.a = a;
op.b = b;
op.c = ExpressionTemporary();
if ( opp ) {
*opp = &op;
}
return op.c;
}
/*
================
sdRequirementCondition::ParseEmitOp
================
*/
int sdRequirementCondition::ParseEmitOp( idLexer *src, int a, rexpOpType_t opType, int priority, rexpOp_t** opp ) {
int b = ParseExpressionPriority( src, priority );
return EmitOp( a, b, opType, opp );
}
/*
================
sdRequirementCondition::ParseExpression
================
*/
int sdRequirementCondition::ParseExpression( idLexer *src ) {
const int TOP_PRIORITY = 2;
return ParseExpressionPriority( src, TOP_PRIORITY );
}
/*
================
sdRequirementCondition::ExpressionConstant
================
*/
int sdRequirementCondition::ExpressionConstant( bool v ) {
int i;
for ( i = 0; i < registers.Num(); i++ ) {
if ( !registers[ i ].temporary && registers[ i ].value == v ) {
return i;
}
}
i = registers.Num();
expressionRegister_t& r = registers.Alloc();
r.temporary = false;
r.value = v;
return i;
}
/*
================
sdRequirementCondition::ParseTerm
=================
*/
int sdRequirementCondition::ParseTerm( idLexer *src ) {
idToken token;
int a;
src->ReadToken( &token );
if ( token == "(" ) {
a = ParseExpression( src );
src->ExpectTokenString( ")" );
return a;
}
if ( !token.Icmp( "true" ) ) {
return ExpressionConstant( true );
}
if ( !token.Icmp( "false" ) ) {
return ExpressionConstant( false );
}
const sdDeclRequirement* requirement = gameLocal.declRequirementType[ token ];
if ( requirement ) {
return ExpressionRequirement( requirement );
}
src->Error( "sdRequirementCondition::ParseTerm Invalid Term '%s'", token.c_str() );
return -1;
}
/*
================
sdRequirementCondition::ExpressionRequirement
================
*/
int sdRequirementCondition::ExpressionRequirement( const sdDeclRequirement* requirement ) {
int i = ExpressionTemporary();
expressionRequirement_t& er = requirements.Alloc();
er.requirement = requirement;
er.index = i;
return i;
}
/*
=================
sdRequirementCondition::ParseExpressionPriority
=================
*/
int sdRequirementCondition::ParseExpressionPriority( idLexer *src, int priority ) {
idToken token;
int a = -1;
if ( priority == 0 ) {
return ParseTerm( src );
}
a = ParseExpressionPriority( src, priority - 1 );
if ( !src->ReadToken( &token ) ) {
return a;
}
switch( priority ) {
case 1: {
if ( token == "==" ) {
return ParseEmitOp( src, a, ROP_TYPE_EQ, priority );
}
if ( token == "!=" ) {
return ParseEmitOp( src, a, ROP_TYPE_NE, priority );
}
src->UnreadToken( &token );
return a;
}
case 2: {
if ( token == "&&" ) {
return ParseEmitOp( src, a, ROP_TYPE_AND, priority );
}
if ( token == "||" ) {
return ParseEmitOp( src, a, ROP_TYPE_OR, priority );
}
src->UnreadToken( &token );
return a; // FIXME: this is not correct, but I cba fixing this parser atm
}
}
// assume that anything else terminates the expression
// not too robust error checking...
src->Error( "sdRequirementCondition::ParseExpressionPriority Unknown Token '%s'", token.c_str() );
return a;
}
/*
================
sdRequirementCondition::Evaluate
================
*/
bool sdRequirementCondition::Evaluate( idEntity* main, idEntity* other ) {
int i;
for ( i = 0; i < requirements.Num(); i++ ) {
registers[ requirements[ i ].index ].value = requirements[ i ].requirement->Check( main, other );
}
for ( i = 0 ; i < ops.Num() ; i++ ) {
rexpOp_t& op = ops[ i ];
switch( op.opType ) {
case ROP_TYPE_EQ:
registers[ op.c ].value = registers[ op.a ].value == registers[ op.b ].value;
break;
case ROP_TYPE_NE:
registers[ op.c ].value = registers[ op.a ].value != registers[ op.b ].value;
break;
case ROP_TYPE_AND:
registers[ op.c ].value = registers[ op.a ].value && registers[ op.b ].value;
break;
case ROP_TYPE_OR:
registers[ op.c ].value = registers[ op.a ].value || registers[ op.b ].value;
break;
default:
gameLocal.Error( "sdFloatParmExpression::EvaluateRegisters: bad opcode" );
break;
}
}
return registers[ valueRegister ].value;
}
/*
===============================================================================
sdRequirementContainer
===============================================================================
*/
/*
================
sdRequirementContainer::Load
================
*/
void sdRequirementContainer::Load( const idDict& requirementList, const char* mode ) {
const idKeyValue* kv = NULL;
while( kv = requirementList.MatchPrefix( mode, kv ) ) {
if( kv->GetValue().Length() <= 0 ) {
continue;
}
Load( kv->GetValue().c_str() );
}
}
/*
================
sdRequirementContainer::Load
================
*/
void sdRequirementContainer::Load( const char* requirement ) {
if ( !*requirement ) {
return;
}
Alloc() = new sdRequirementCondition( requirement );
}
/*
================
sdRequirementContainer::~sdRequirementContainer
================
*/
sdRequirementContainer::~sdRequirementContainer( void ) {
DeleteContents( true );
}
/*
================
sdRequirementContainer::Check
================
*/
bool sdRequirementContainer::Check( idEntity* main, idEntity* other ) const {
int i;
for( i = 0; i < Num(); i++ ) {
if( !( *this )[ i ]->Evaluate( main, other ) ) {
return false;
}
}
// All requirement checks passed, let 'em have it
return true;
}
/*
===============================================================================
sdAbilityProvider
===============================================================================
*/
/*
================
sdAbilityProvider::Add
================
*/
void sdAbilityProvider::Add( const char* abilityName ) {
Alloc() = sdRequirementManager::GetInstance().RegisterAbility( abilityName );
}
/*
===============================================================================
sdRequirementManagerLocal
===============================================================================
*/
/*
================
sdRequirementManagerLocal::sdRequirementManagerLocal
================
*/
sdRequirementManagerLocal::sdRequirementManagerLocal( void ) {
}
/*
================
sdRequirementManagerLocal::~sdRequirementManagerLocal
================
*/
sdRequirementManagerLocal::~sdRequirementManagerLocal( void ) {
Shutdown();
}
/*
================
sdRequirementManagerLocal::Init
================
*/
void sdRequirementManagerLocal::Init( void ) {
}
/*
================
sdRequirementManagerLocal::Shutdown
================
*/
void sdRequirementManagerLocal::Shutdown( void ) {
registeredAbilities.Clear();
}
/*
================
sdRequirementManagerLocal::RegisterRequirement
================
*/
qhandle_t sdRequirementManagerLocal::RegisterAbility( const char* name ) {
qhandle_t* handle = NULL;
if ( registeredAbilities.Get( name, &handle ) ) {
return *handle;
}
return registeredAbilities.Set( name, ( qhandle_t )registeredAbilities.Num() );
}