khanat-opennel-code/code/ryzom/server/src/ai_service/ai_script_comp.cpp

1093 lines
25 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdpch.h"
#include "ai_generic_fight.h"
#include "ai_script_comp.h"
#include "server_share/msg_brick_service.h"
using namespace std;
using namespace NLMISC;
// renvoie le bout de la string jusqu'au prochain ',' en respectant les priorités des parenthèses.
void explodeSubStrings(const std::string &str, vector<std::string> &strings, sint32 parenthesis=0)
{
const std::string separators("(),");
string::size_type current=0;
string::size_type nextCurrent=current;
strings.clear();
nextCurrent=str.find_first_of(separators.c_str(), current);
while (nextCurrent!=std::string::npos)
{
switch(str.at(nextCurrent))
{
case '(':
parenthesis++;
if (parenthesis==0)
{
current=nextCurrent+1;
}
break;
case ')':
if (parenthesis==0)
{
strings.push_back(str.substr(current, nextCurrent-current));
current=nextCurrent+1;
}
parenthesis--;
break;
case ',':
if (parenthesis==0)
{
strings.push_back(str.substr(current, nextCurrent-current));
current=nextCurrent+1;
}
break;
default:
break;
}
nextCurrent=str.find_first_of(separators.c_str(), nextCurrent+1);
}
}
//////////////////////////////////////////////////////////////////////////
// Select Filter
bool CFightSelectFilter::update (CSpawnBot &bot) const
{
return _CustomComp->update(bot);
// nlassert("a filter is not designed to be updated");
}
std::string CFightSelectFilter::toString() const
{
return "SELECT("+_Param+","+_CustomComp->toString()+")";
}
CFightScriptComp *CFightSelectFilterReader::create (const std::string &inStr) throw (ReadFightActionException)
{
std::vector<std::string> params;
explodeSubStrings(inStr, params, -1);
if (params.size()!=2)
throw ReadFightActionException("SELECT Needs 2 Params: <Filter>,<ScriptComp>");
CSmartPtr<CFightScriptComp> scriptComp;
try
{
scriptComp=createScriptComp(params[1]);
}
catch (ReadFightActionException &ex)
{
throw ReadFightActionException("cannot create sub ScriptComp : "+std::string(ex.what()));
}
return new CFightSelectFilter(scriptComp, params[0]);
}
//////////////////////////////////////////////////////////////////////////
// Once
class CFightOnce
:public CFightScriptComp
{
public:
CFightOnce(CFightScriptComp *customComp)
:_CustomComp(customComp)
{
nlassert(customComp); // the creature is hitting, we cannot do anything ..
}
virtual ~CFightOnce()
{}
bool update (CSpawnBot &bot) const
{
uint32 dummy;
if (bot.getProp((size_t)this,dummy)) // check if we already go there (for once).
return true;
if (!_CustomComp->update(bot))
return false;
bot.setProp((size_t)this,1);
return true;
}
string toString() const
{
return "ONCE("+_CustomComp->toString()+")";
}
protected:
private:
NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
};
class CFightOnceReader
:public CFightScriptCompReader
{
public:
CFightOnceReader() {}
virtual ~CFightOnceReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> params;
explodeSubStrings(inStr, params, -1);
if (params.size()!=1)
throw ReadFightActionException("ONCE Needs 1 Param: <ScriptComp>");
CSmartPtr<CFightScriptComp> scriptComp;
try
{
scriptComp=createScriptComp(params[0]);
}
catch (ReadFightActionException &ex)
{
throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
}
return new CFightOnce(scriptComp);
}
std::string getName () const
{
return std::string("ONCE");
}
};
//////////////////////////////////////////////////////////////////////////
// Timed Filter
class CFightTimedFilter
:public CFightScriptComp
{
public:
CFightTimedFilter(CFightScriptComp *customComp, uint32 deltaTime)
:_CustomComp(customComp)
,_DeltaTime(deltaTime)
{
nlassert(customComp); // the creature is hitting, we cannot do anything ..
}
virtual ~CFightTimedFilter()
{}
bool update (CSpawnBot &bot) const
{
uint32 decTime=0;
if (bot.getProp((size_t)this, decTime))
if (CTimeInterface::gameCycle()<decTime)
return true;
if (!_CustomComp->update(bot))
return false;
bot.setProp((size_t)this, CTimeInterface::gameCycle()+(uint32)_DeltaTime);
return true;
}
string toString() const
{
return "EVERY_SEC("+NLMISC::toString(_DeltaTime/10)+","+_CustomComp->toString()+")";
}
protected:
private:
NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
uint32 _DeltaTime;
};
class CFightTimedFilterReader
:public CFightScriptCompReader
{
public:
CFightTimedFilterReader() {}
virtual ~CFightTimedFilterReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> params;
explodeSubStrings(inStr, params, -1);
if (params.size()!=2)
throw ReadFightActionException("EVERY_SEC Needs 2 Params: <time in seconds>,<ScriptComp>");
int time=atoi(params[0].c_str())*10;
CSmartPtr<CFightScriptComp> scriptComp;
try
{
scriptComp=createScriptComp(params[1]);
}
catch (ReadFightActionException &ex)
{
throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
}
return new CFightTimedFilter(scriptComp, time);
}
std::string getName () const
{
return std::string("EVERY_SEC");
}
};
//////////////////////////////////////////////////////////////////////////
// HP Less Filter
class CFightHPLessFilter
:public CFightScriptComp
{
public:
CFightHPLessFilter(CFightScriptComp *customComp, float hpLimit)
:_CustomComp(customComp)
,_HPLimit(hpLimit)
{
nlassert(customComp); // comportment needed.
}
virtual ~CFightHPLessFilter()
{}
bool update (CSpawnBot &bot) const
{
if (bot.hpPercentage()>=_HPLimit)
return true;
return _CustomComp->update(bot);
}
string toString() const
{
return "HP%LESS("+NLMISC::toString(_HPLimit)+","+_CustomComp->toString()+")";
}
protected:
private:
NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
float _HPLimit;
};
class CFightHPLessFilterReader
:public CFightScriptCompReader
{
public:
CFightHPLessFilterReader() {}
virtual ~CFightHPLessFilterReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> params;
explodeSubStrings(inStr, params, -1);
if (params.size()!=2)
throw ReadFightActionException("HP%LESS Needs 2 Params: <hp limit>,<ScriptComp>");
float hpLimit=(float)atof(params[0].c_str());
CSmartPtr<CFightScriptComp> scriptComp;
try
{
scriptComp=createScriptComp(params[1]);
}
catch (ReadFightActionException &ex)
{
throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
}
return new CFightHPLessFilter(scriptComp, hpLimit);
}
std::string getName () const
{
return std::string("HP%LESS");
}
};
//////////////////////////////////////////////////////////////////////////
// HP More Filter
class CFightHPMoreFilter
:public CFightScriptComp
{
public:
CFightHPMoreFilter(CFightScriptComp *customComp, float hpLimit)
:_CustomComp(customComp)
,_HPLimit(hpLimit)
{
nlassert(customComp); // comportment needed.
}
virtual ~CFightHPMoreFilter()
{}
bool update (CSpawnBot &bot) const
{
if (bot.hpPercentage()<=_HPLimit)
return true;
return _CustomComp->update(bot);
}
string toString() const
{
return "HP%MORE("+NLMISC::toString(_HPLimit)+","+_CustomComp->toString()+")";
}
protected:
private:
NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
float _HPLimit;
};
class CFightHPMoreFilterReader
:public CFightScriptCompReader
{
public:
CFightHPMoreFilterReader() {}
virtual ~CFightHPMoreFilterReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> params;
explodeSubStrings(inStr, params, -1);
if (params.size()!=2)
throw ReadFightActionException("HP%MORE Needs 2 Params: <hp limit>,<ScriptComp>");
float hpLimit=(float)atof(params[0].c_str());
CSmartPtr<CFightScriptComp> scriptComp;
try
{
scriptComp=createScriptComp(params[1]);
}
catch (ReadFightActionException &ex)
{
throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
}
return new CFightHPMoreFilter(scriptComp, hpLimit);
}
std::string getName () const
{
return std::string("HP%MORE");
}
};
//////////////////////////////////////////////////////////////////////////
// Random Filter
class CFightRandomFilter
:public CFightScriptComp
{
public:
CFightRandomFilter(CFightScriptComp *customComp, float random)
:_CustomComp(customComp)
,_Random(random)
{
nlassert(customComp); // comportment needed.
}
virtual ~CFightRandomFilter()
{}
bool update (CSpawnBot &bot) const
{
if (CAIS::rand16(32767)>=(_Random*32767))
return true;
return _CustomComp->update(bot);
}
string toString() const
{
return "RANDOM("+NLMISC::toString(_Random)+","+_CustomComp->toString()+")";
}
protected:
private:
NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
float _Random;
};
class CFightRandomFilterReader
:public CFightScriptCompReader
{
public:
CFightRandomFilterReader() {}
virtual ~CFightRandomFilterReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> params;
explodeSubStrings(inStr, params, -1);
if (params.size()!=2)
throw ReadFightActionException("RANDOM Needs 2 Params: <proba>,<ScriptComp>");
float random=(float)atof(params[0].c_str());
CSmartPtr<CFightScriptComp> scriptComp;
try
{
scriptComp=createScriptComp(params[1]);
}
catch (ReadFightActionException &ex)
{
throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
}
return new CFightRandomFilter(scriptComp, random);
}
std::string getName () const
{
return std::string("RANDOM");
}
};
//////////////////////////////////////////////////////////////////////////
// Send Action
class CFightSendAction
:public CFightScriptComp
{
public:
CFightSendAction(AISHEETS::IAIActionCPtr action, string const& actionName)
: _Action(action)
, _ActionName(actionName)
{
}
virtual ~CFightSendAction() { }
bool update(CSpawnBot &bot) const
{
if (!bot.getAIProfile())
return true;
CBotProfileFight *profile=dynamic_cast<CBotProfileFight*>(bot.getAIProfile());
if (!profile)
return true;
if (!profile->atAttackDist())
return false;
TDataSetRow dataSetRow;
if ((CAIEntityPhysical*)bot.getTarget())
dataSetRow=bot.getTarget()->dataSetRow();
CEGSExecuteAiActionMsg msg(bot.dataSetRow(), dataSetRow, _Action->SheetId(), bot._DamageCoef, bot._DamageSpeedCoef);
msg.send(egsString);
bot.setActionFlags(RYZOMACTIONFLAGS::Attacks);
return true;
}
string toString() const
{
return "SEND_ACTION("+_ActionName+")";
}
protected:
private:
string _ActionName;
AISHEETS::IAIActionCPtr _Action;
};
class CFightSendActionReader
:public CFightScriptCompReader
{
public:
CFightSendActionReader() {}
virtual ~CFightSendActionReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> strings;
explodeSubStrings(inStr, strings, -1);
if (strings.size()!=1)
throw ReadFightActionException("SEND_ACTION Needs 1 param");
NLMISC::CSheetId sheetId(strings[0].c_str());
if (sheetId==NLMISC::CSheetId::Unknown)
throw ReadFightActionException("SheetId Unknown "+inStr);
AISHEETS::IAIActionCPtr action = AISHEETS::CSheets::getInstance()->lookupAction(sheetId);
if (action.isNull())
throw ReadFightActionException("SheetId Unknown "+inStr);
return new CFightSendAction(action, strings[0]);
}
std::string getName () const
{
return std::string("SEND_ACTION");
}
};
//////////////////////////////////////////////////////////////////////////
// Send Self Action
class CFightSendSelfAction
:public CFightScriptComp
{
public:
CFightSendSelfAction(AISHEETS::IAIActionCPtr action, string const& actionName)
: _Action(action)
, _ActionName(actionName)
{
}
virtual ~CFightSendSelfAction() { }
bool update(CSpawnBot &bot) const
{
CEGSExecuteAiActionMsg msg(bot.dataSetRow(), bot.dataSetRow(), _Action->SheetId(), bot._DamageCoef, bot._DamageSpeedCoef);
msg.send(egsString);
bot.setActionFlags(RYZOMACTIONFLAGS::Attacks);
return true;
}
string toString() const
{
return "SEND_SELF_ACTION("+_ActionName+")";
}
protected:
private:
string _ActionName;
AISHEETS::IAIActionCPtr _Action;
};
class CFightSendSelfActionReader
:public CFightScriptCompReader
{
public:
CFightSendSelfActionReader() {}
virtual ~CFightSendSelfActionReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> strings;
explodeSubStrings(inStr, strings, -1);
if (strings.size()!=1)
throw ReadFightActionException("SEND_SELF_ACTION Needs 1 param");
NLMISC::CSheetId sheetId(strings[0].c_str());
if (sheetId==NLMISC::CSheetId::Unknown)
throw ReadFightActionException("SheetId Unknown "+inStr);
AISHEETS::IAIActionCPtr action = AISHEETS::CSheets::getInstance()->lookupAction(sheetId);
if (action.isNull())
throw ReadFightActionException("SheetId Unknown "+inStr);
return new CFightSendSelfAction(action, strings[0]);
}
std::string getName () const
{
return std::string("SEND_SELF_ACTION");
}
};
//////////////////////////////////////////////////////////////////////////
// AggroBlock
class CFightAggroBlock
:public CFightScriptComp
{
public:
CFightAggroBlock(const uint32 time):_Time(time)
{}
virtual ~CFightAggroBlock()
{}
bool update(CSpawnBot &bot) const
{
bot.blockAggro(_Time);
return true;
}
string toString() const
{
return "AGGRO_BLOCK("+NLMISC::toString(_Time/10)+")";
}
protected:
private:
uint32 _Time;
};
class CFightAggroBlockReader
:public CFightScriptCompReader
{
public:
CFightAggroBlockReader() {}
virtual ~CFightAggroBlockReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> strings;
explodeSubStrings(inStr, strings, -1);
if (strings.size()!=1)
throw ReadFightActionException("AGGRO_BLOCK Needs 1 param");
uint32 time=atoi(strings[0].c_str())*10;
return new CFightAggroBlock(time);
}
std::string getName () const
{
return std::string("AGGRO_BLOCK");
}
};
//////////////////////////////////////////////////////////////////////////
// AggroChange
class CFightAggroChange
:public CFightScriptComp
{
public:
CFightAggroChange()
{}
virtual ~CFightAggroChange()
{}
bool update(CSpawnBot &bot) const
{
CAIEntityPhysical *target=bot.getTarget();
if (!target)
return true;
bot.minimizeAggroFor(target->dataSetRow());
return true;
}
string toString() const
{
return "AGGRO_CHANGE()";
}
protected:
private:
};
class CFightAggroChangeReader
:public CFightScriptCompReader
{
public:
CFightAggroChangeReader() {}
virtual ~CFightAggroChangeReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
return new CFightAggroChange();
}
std::string getName () const
{
return std::string("AGGRO_CHANGE");
}
};
//////////////////////////////////////////////////////////////////////////
// DamageCoef
class CFightDamageCoef
:public CFightScriptComp
{
public:
CFightDamageCoef(const float coef) :_Coef(coef)
{}
virtual ~CFightDamageCoef()
{}
bool update(CSpawnBot &bot) const
{
bot._DamageCoef=_Coef;
return true;
}
string toString() const
{
return "DAMAGE_COEF("+NLMISC::toString(_Coef)+")";
}
protected:
private:
float _Coef;
};
class CFightDamageCoefReader
:public CFightScriptCompReader
{
public:
CFightDamageCoefReader() {}
virtual ~CFightDamageCoefReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> strings;
explodeSubStrings(inStr, strings, -1);
if (strings.size()!=1)
throw ReadFightActionException("DAMAGE_COEF Needs 1 param");
const float coef=(float)atof(strings[0].c_str());
return new CFightDamageCoef(coef);
}
std::string getName () const
{
return std::string("DAMAGE_COEF");
}
};
//////////////////////////////////////////////////////////////////////////
// GroupDamageCoef
class CFightGroupDamageCoef
:public CFightScriptComp
{
public:
CFightGroupDamageCoef(const float coef) :_Coef(coef)
{}
virtual ~CFightGroupDamageCoef()
{}
bool update(CSpawnBot &bot) const
{
CSpawnGroup &spawnGroup=bot.spawnGrp();
CAliasCont<CBot> &bots=spawnGroup.getPersistent().bots();
float damageCoef=1.f;
for (sint32 nbRec=bots.size()-(spawnGroup.nbSpawnedBot()+spawnGroup.nbBotToDespawn());nbRec>=0;nbRec--)
damageCoef*=_Coef;
for (CCont<CBot>::iterator it=bots.begin(), itEnd=bots.end(); it!=itEnd; ++it)
{
CSpawnBot *spawnBot=it->getSpawnObj();
if (spawnBot)
spawnBot->_DamageCoef=damageCoef;
}
return true;
}
string toString() const
{
return "UPDATE_GROUP_DAMAGE_COEF("+NLMISC::toString(_Coef)+")";
}
protected:
private:
float _Coef;
};
class CFightGroupDamageCoefReader
:public CFightScriptCompReader
{
public:
CFightGroupDamageCoefReader() {}
virtual ~CFightGroupDamageCoefReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> strings;
explodeSubStrings(inStr, strings, -1);
if (strings.size()!=1)
throw ReadFightActionException("UPDATE_GROUP_DAMAGE_COEF Needs 1 param");
const float coef=(float)atof(strings[0].c_str());
return new CFightGroupDamageCoef(coef);
}
std::string getName () const
{
return std::string("UPDATE_GROUP_DAMAGE_COEF");
}
};
//////////////////////////////////////////////////////////////////////////
// DamageSpeedCoef
class CFightDamageSpeedCoef
:public CFightScriptComp
{
public:
CFightDamageSpeedCoef(const float coef) :_Coef(coef)
{}
virtual ~CFightDamageSpeedCoef()
{}
bool update(CSpawnBot &bot) const
{
bot._DamageSpeedCoef=_Coef;
return true;
}
string toString() const
{
return "DAMAGE_SPEED_COEF("+NLMISC::toString(_Coef)+")";
}
protected:
private:
float _Coef;
};
class CFightDamageSpeedCoefReader
:public CFightScriptCompReader
{
public:
CFightDamageSpeedCoefReader() {}
virtual ~CFightDamageSpeedCoefReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> strings;
explodeSubStrings(inStr, strings, -1);
if (strings.size()!=1)
throw ReadFightActionException("DAMAGE_SPEED_COEF Needs 1 param");
const float coef=(float)atof(strings[0].c_str());
return new CFightDamageSpeedCoef(coef);
}
std::string getName () const
{
return std::string("DAMAGE_SPEED_COEF");
}
};
//////////////////////////////////////////////////////////////////////////
// SetRandomTarget
class CFightSetRandomTarget
:public CFightScriptComp
{
public:
CFightSetRandomTarget(const float coef) :_Coef(coef)
{}
virtual ~CFightSetRandomTarget()
{}
bool update(CSpawnBot &bot) const
{
const CBotAggroOwner::TBotAggroList &list=bot.getBotAggroList();
size_t size = list.size();
if (size>0)
{
CBotAggroOwner::TBotAggroList::const_iterator it = list.begin();
for (size_t i=0; i<size; ++i)
++it;
if (it!=list.end())
bot.maximizeAggroFor(it->first);
}
return true;
}
string toString() const
{
return "SET_RANDOM_TARGET()";
}
protected:
private:
float _Coef;
};
class CFightSetRandomTargetReader
:public CFightScriptCompReader
{
public:
CFightSetRandomTargetReader() {}
virtual ~CFightSetRandomTargetReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> strings;
explodeSubStrings(inStr, strings, -1);
if ( strings.size()!=1
|| strings[0]!="")
throw ReadFightActionException("SET_RANDOM_TARGET Needs 0 param");
const float coef=(float)atof(strings[0].c_str());
return new CFightSetRandomTarget(coef);
}
std::string getName () const
{
return std::string("SET_RANDOM_TARGET");
}
};
//////////////////////////////////////////////////////////////////////////
// Once
class CFightMult
:public CFightScriptComp
{
public:
CFightMult(const std::vector<CSmartPtr<CFightScriptComp> > &customComps)
:_CustomComps(customComps)
{
}
virtual ~CFightMult()
{}
bool update (CSpawnBot &bot) const
{
for (uint32 i=0;i<_CustomComps.size();i++)
_CustomComps[i]->update(bot);
return true;
}
string toString() const
{
string outputString="MULT(";
for (uint32 i=0;i<_CustomComps.size();i++)
{
if (i>0)
outputString+=","; // add a "," to separate this param from previous ..
outputString+=_CustomComps[i]->toString();
}
return outputString+")";
}
protected:
private:
const std::vector<CSmartPtr<CFightScriptComp> > _CustomComps;
};
class CFightMultReader
:public CFightScriptCompReader
{
public:
CFightMultReader() {}
virtual ~CFightMultReader() {}
CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException)
{
vector<string> params;
explodeSubStrings(inStr, params, -1);
const uint32 nbSubScript=(uint32)params.size();
std::vector<CSmartPtr<CFightScriptComp> > scriptComps;
try
{
for (uint32 i=0;i<nbSubScript;i++)
scriptComps.push_back(createScriptComp(params[i]));
}
catch (ReadFightActionException &ex)
{
throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
}
return new CFightMult(scriptComps);
}
std::string getName () const
{
return std::string("MULT");
}
};
//////////////////////////////////////////////////////////////////////////
// CFightScript
CFightScript::TFightScriptMap CFightScript::_ScriptCompList;
CFightScript justInstanciatedToRegisterReaders;
CFightScript::CFightScript()
{
add(new CFightSelectFilterReader());
add(new CFightMultReader());
add(new CFightOnceReader());
add(new CFightTimedFilterReader());
add(new CFightRandomFilterReader());
add(new CFightHPLessFilterReader());
add(new CFightHPMoreFilterReader());
add(new CFightAggroBlockReader());
add(new CFightAggroChangeReader());
add(new CFightDamageCoefReader());
add(new CFightGroupDamageCoefReader());
add(new CFightDamageSpeedCoefReader());
add(new CFightSendActionReader());
add(new CFightSendSelfActionReader());
add(new CFightSetRandomTargetReader());
}
void CFightScript::add(CFightScriptCompReader *reader)
{
nlassert(reader!=NULL);
nlassert(_ScriptCompList.find(reader->getName())==_ScriptCompList.end());
_ScriptCompList.insert(std::make_pair(reader->getName(),reader));
}
CFightScriptCompReader *CFightScriptCompReader::getScriptReader (const string &str) throw (ReadFightActionException)
{
CFightScript::TFightScriptMap::iterator it=CFightScript::_ScriptCompList.find(str);
if (it==CFightScript::_ScriptCompList.end())
throw ReadFightActionException("Unknown ScriptComp "+str);
return &(*(it->second));
}
CFightScriptComp *CFightScriptCompReader::createScriptComp (const string &str) throw (ReadFightActionException)
{
string scriptCompName;
{
const string::size_type index=str.find_first_of("()", 0);
if (index==string::npos)
throw ReadFightActionException("ScriptComp Creation of :"+str+" Failed because of bad Syntax");
scriptCompName=str.substr(0,index);
}
try
{
return getScriptReader (scriptCompName)->create(str);
}
catch (ReadFightActionException &e)
{
throw ReadFightActionException(string("ScriptComp creation failed : ")+string(e.what()));
}
}