Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / ai_service / ai_script_comp.cpp
blob4993163bab5b67b17a43fa243cf8fc9d266cb45b
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "stdpch.h"
18 #include "ai_generic_fight.h"
19 #include "ai_script_comp.h"
20 #include "server_share/msg_brick_service.h"
22 using namespace std;
23 using namespace NLMISC;
25 // renvoie le bout de la string jusqu'au prochain ',' en respectant les priorités des parenthèses.
26 void explodeSubStrings(const std::string &str, vector<std::string> &strings, sint32 parenthesis=0)
28 const std::string separators("(),");
29 string::size_type current=0;
30 string::size_type nextCurrent=current;
31 strings.clear();
33 nextCurrent=str.find_first_of(separators.c_str(), current);
34 while (nextCurrent!=std::string::npos)
36 switch(str.at(nextCurrent))
38 case '(':
39 parenthesis++;
40 if (parenthesis==0)
42 current=nextCurrent+1;
44 break;
45 case ')':
46 if (parenthesis==0)
48 strings.push_back(str.substr(current, nextCurrent-current));
49 current=nextCurrent+1;
51 parenthesis--;
52 break;
53 case ',':
54 if (parenthesis==0)
56 strings.push_back(str.substr(current, nextCurrent-current));
57 current=nextCurrent+1;
59 break;
60 default:
61 break;
63 nextCurrent=str.find_first_of(separators.c_str(), nextCurrent+1);
70 //////////////////////////////////////////////////////////////////////////
71 // Select Filter
73 bool CFightSelectFilter::update (CSpawnBot &bot) const
75 return _CustomComp->update(bot);
76 // nlassert("a filter is not designed to be updated");
79 std::string CFightSelectFilter::toString() const
81 return "SELECT("+_Param+","+_CustomComp->toString()+")";
86 CFightScriptComp *CFightSelectFilterReader::create (const std::string &inStr)
88 std::vector<std::string> params;
89 explodeSubStrings(inStr, params, -1);
91 if (params.size()!=2)
92 throw ReadFightActionException("SELECT Needs 2 Params: <Filter>,<ScriptComp>");
94 CSmartPtr<CFightScriptComp> scriptComp;
95 try
97 scriptComp=createScriptComp(params[1]);
99 catch (const ReadFightActionException &ex)
101 throw ReadFightActionException("cannot create sub ScriptComp : "+std::string(ex.what()));
103 return new CFightSelectFilter(scriptComp, params[0]);
107 //////////////////////////////////////////////////////////////////////////
108 // Once
111 class CFightOnce
112 :public CFightScriptComp
114 public:
115 CFightOnce(CFightScriptComp *customComp)
116 :_CustomComp(customComp)
118 nlassert(customComp); // the creature is hitting, we cannot do anything ..
121 virtual ~CFightOnce()
123 bool update (CSpawnBot &bot) const
125 uint32 dummy;
126 if (bot.getProp((size_t)this,dummy)) // check if we already go there (for once).
127 return true;
129 if (!_CustomComp->update(bot))
130 return false;
132 bot.setProp((size_t)this,1);
133 return true;
136 string toString() const
138 return "ONCE("+_CustomComp->toString()+")";
141 protected:
142 private:
143 NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
147 class CFightOnceReader
148 :public CFightScriptCompReader
150 public:
151 CFightOnceReader() {}
152 virtual ~CFightOnceReader() {}
154 CFightScriptComp *create (const std::string &inStr)
156 vector<string> params;
157 explodeSubStrings(inStr, params, -1);
159 if (params.size()!=1)
160 throw ReadFightActionException("ONCE Needs 1 Param: <ScriptComp>");
162 CSmartPtr<CFightScriptComp> scriptComp;
165 scriptComp=createScriptComp(params[0]);
167 catch (const ReadFightActionException &ex)
169 throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
171 return new CFightOnce(scriptComp);
173 std::string getName () const
175 return std::string("ONCE");
182 //////////////////////////////////////////////////////////////////////////
183 // Timed Filter
186 class CFightTimedFilter
187 :public CFightScriptComp
189 public:
190 CFightTimedFilter(CFightScriptComp *customComp, uint32 deltaTime)
191 :_CustomComp(customComp)
192 ,_DeltaTime(deltaTime)
194 nlassert(customComp); // the creature is hitting, we cannot do anything ..
197 virtual ~CFightTimedFilter()
199 bool update (CSpawnBot &bot) const
201 uint32 decTime=0;
202 if (bot.getProp((size_t)this, decTime))
203 if (CTimeInterface::gameCycle()<decTime)
204 return true;
206 if (!_CustomComp->update(bot))
207 return false;
209 bot.setProp((size_t)this, CTimeInterface::gameCycle()+(uint32)_DeltaTime);
210 return true;
213 string toString() const
215 return "EVERY_SEC("+NLMISC::toString(_DeltaTime/10)+","+_CustomComp->toString()+")";
218 protected:
219 private:
220 NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
221 uint32 _DeltaTime;
225 class CFightTimedFilterReader
226 :public CFightScriptCompReader
228 public:
229 CFightTimedFilterReader() {}
230 virtual ~CFightTimedFilterReader() {}
232 CFightScriptComp *create (const std::string &inStr)
234 vector<string> params;
235 explodeSubStrings(inStr, params, -1);
237 if (params.size()!=2)
238 throw ReadFightActionException("EVERY_SEC Needs 2 Params: <time in seconds>,<ScriptComp>");
240 sint time;
241 NLMISC::fromString(params[0], time);
242 time *= 10;
244 CSmartPtr<CFightScriptComp> scriptComp;
247 scriptComp=createScriptComp(params[1]);
249 catch (const ReadFightActionException &ex)
251 throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
253 return new CFightTimedFilter(scriptComp, time);
255 std::string getName () const
257 return std::string("EVERY_SEC");
263 //////////////////////////////////////////////////////////////////////////
264 // HP Less Filter
266 class CFightHPLessFilter
267 :public CFightScriptComp
269 public:
270 CFightHPLessFilter(CFightScriptComp *customComp, float hpLimit)
271 :_CustomComp(customComp)
272 ,_HPLimit(hpLimit)
274 nlassert(customComp); // comportment needed.
277 virtual ~CFightHPLessFilter()
279 bool update (CSpawnBot &bot) const
281 if (bot.hpPercentage()>=_HPLimit)
282 return true;
283 return _CustomComp->update(bot);
286 string toString() const
288 return "HP%LESS("+NLMISC::toString(_HPLimit)+","+_CustomComp->toString()+")";
291 protected:
292 private:
293 NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
294 float _HPLimit;
298 class CFightHPLessFilterReader
299 :public CFightScriptCompReader
301 public:
302 CFightHPLessFilterReader() {}
303 virtual ~CFightHPLessFilterReader() {}
305 CFightScriptComp *create (const std::string &inStr)
307 vector<string> params;
308 explodeSubStrings(inStr, params, -1);
310 if (params.size()!=2)
311 throw ReadFightActionException("HP%LESS Needs 2 Params: <hp limit>,<ScriptComp>");
313 float hpLimit=(float)atof(params[0].c_str());
315 CSmartPtr<CFightScriptComp> scriptComp;
318 scriptComp=createScriptComp(params[1]);
320 catch (const ReadFightActionException &ex)
322 throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
324 return new CFightHPLessFilter(scriptComp, hpLimit);
326 std::string getName () const
328 return std::string("HP%LESS");
333 //////////////////////////////////////////////////////////////////////////
334 // HP More Filter
336 class CFightHPMoreFilter
337 :public CFightScriptComp
339 public:
340 CFightHPMoreFilter(CFightScriptComp *customComp, float hpLimit)
341 :_CustomComp(customComp)
342 ,_HPLimit(hpLimit)
344 nlassert(customComp); // comportment needed.
347 virtual ~CFightHPMoreFilter()
349 bool update (CSpawnBot &bot) const
351 if (bot.hpPercentage()<=_HPLimit)
352 return true;
353 return _CustomComp->update(bot);
356 string toString() const
358 return "HP%MORE("+NLMISC::toString(_HPLimit)+","+_CustomComp->toString()+")";
361 protected:
362 private:
363 NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
364 float _HPLimit;
368 class CFightHPMoreFilterReader
369 :public CFightScriptCompReader
371 public:
372 CFightHPMoreFilterReader() {}
373 virtual ~CFightHPMoreFilterReader() {}
375 CFightScriptComp *create (const std::string &inStr)
377 vector<string> params;
378 explodeSubStrings(inStr, params, -1);
380 if (params.size()!=2)
381 throw ReadFightActionException("HP%MORE Needs 2 Params: <hp limit>,<ScriptComp>");
383 float hpLimit=(float)atof(params[0].c_str());
385 CSmartPtr<CFightScriptComp> scriptComp;
388 scriptComp=createScriptComp(params[1]);
390 catch (const ReadFightActionException &ex)
392 throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
394 return new CFightHPMoreFilter(scriptComp, hpLimit);
396 std::string getName () const
398 return std::string("HP%MORE");
404 //////////////////////////////////////////////////////////////////////////
405 // Random Filter
407 class CFightRandomFilter
408 :public CFightScriptComp
410 public:
411 CFightRandomFilter(CFightScriptComp *customComp, float random)
412 :_CustomComp(customComp)
413 ,_Random(random)
415 nlassert(customComp); // comportment needed.
418 virtual ~CFightRandomFilter()
420 bool update (CSpawnBot &bot) const
422 if (CAIS::rand16(32767)>=(_Random*32767))
423 return true;
424 return _CustomComp->update(bot);
427 string toString() const
429 return "RANDOM("+NLMISC::toString(_Random)+","+_CustomComp->toString()+")";
432 protected:
433 private:
434 NLMISC::CSmartPtr<CFightScriptComp> _CustomComp;
435 float _Random;
439 class CFightRandomFilterReader
440 :public CFightScriptCompReader
442 public:
443 CFightRandomFilterReader() {}
444 virtual ~CFightRandomFilterReader() {}
446 CFightScriptComp *create (const std::string &inStr)
448 vector<string> params;
449 explodeSubStrings(inStr, params, -1);
451 if (params.size()!=2)
452 throw ReadFightActionException("RANDOM Needs 2 Params: <proba>,<ScriptComp>");
454 float random=(float)atof(params[0].c_str());
456 CSmartPtr<CFightScriptComp> scriptComp;
459 scriptComp=createScriptComp(params[1]);
461 catch (const ReadFightActionException &ex)
463 throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
465 return new CFightRandomFilter(scriptComp, random);
467 std::string getName () const
469 return std::string("RANDOM");
474 //////////////////////////////////////////////////////////////////////////
475 // Send Action
477 class CFightSendAction
478 :public CFightScriptComp
480 public:
481 CFightSendAction(AISHEETS::IAIActionCPtr action, string const& actionName)
482 : _Action(action)
483 , _ActionName(actionName)
487 virtual ~CFightSendAction() { }
488 bool update(CSpawnBot &bot) const
490 if (!bot.getAIProfile())
491 return true;
493 CBotProfileFight *profile=dynamic_cast<CBotProfileFight*>(bot.getAIProfile());
494 if (!profile)
495 return true;
497 if (!profile->atAttackDist())
498 return false;
500 TDataSetRow dataSetRow;
501 if ((CAIEntityPhysical*)bot.getTarget())
502 dataSetRow=bot.getTarget()->dataSetRow();
504 CEGSExecuteAiActionMsg msg(bot.dataSetRow(), dataSetRow, _Action->SheetId(), bot._DamageCoef, bot._DamageSpeedCoef);
505 msg.send(egsString);
506 bot.setActionFlags(RYZOMACTIONFLAGS::Attacks);
507 return true;
509 string toString() const
511 return "SEND_ACTION("+_ActionName+")";
513 protected:
514 private:
515 string _ActionName;
516 AISHEETS::IAIActionCPtr _Action;
519 class CFightSendActionReader
520 :public CFightScriptCompReader
522 public:
523 CFightSendActionReader() {}
524 virtual ~CFightSendActionReader() {}
526 CFightScriptComp *create (const std::string &inStr)
528 vector<string> strings;
529 explodeSubStrings(inStr, strings, -1);
531 if (strings.size()!=1)
532 throw ReadFightActionException("SEND_ACTION Needs 1 param");
534 NLMISC::CSheetId sheetId(strings[0].c_str());
535 if (sheetId==NLMISC::CSheetId::Unknown)
536 throw ReadFightActionException("SheetId Unknown "+inStr);
538 AISHEETS::IAIActionCPtr action = AISHEETS::CSheets::getInstance()->lookupAction(sheetId);
539 if (action.isNull())
540 throw ReadFightActionException("SheetId Unknown "+inStr);
542 return new CFightSendAction(action, strings[0]);
545 std::string getName () const
547 return std::string("SEND_ACTION");
553 //////////////////////////////////////////////////////////////////////////
554 // Send Self Action
556 class CFightSendSelfAction
557 :public CFightScriptComp
559 public:
560 CFightSendSelfAction(AISHEETS::IAIActionCPtr action, string const& actionName)
561 : _Action(action)
562 , _ActionName(actionName)
566 virtual ~CFightSendSelfAction() { }
567 bool update(CSpawnBot &bot) const
569 CEGSExecuteAiActionMsg msg(bot.dataSetRow(), bot.dataSetRow(), _Action->SheetId(), bot._DamageCoef, bot._DamageSpeedCoef);
570 msg.send(egsString);
571 bot.setActionFlags(RYZOMACTIONFLAGS::Attacks);
572 return true;
574 string toString() const
576 return "SEND_SELF_ACTION("+_ActionName+")";
578 protected:
579 private:
580 string _ActionName;
581 AISHEETS::IAIActionCPtr _Action;
584 class CFightSendSelfActionReader
585 :public CFightScriptCompReader
587 public:
588 CFightSendSelfActionReader() {}
589 virtual ~CFightSendSelfActionReader() {}
591 CFightScriptComp *create (const std::string &inStr)
593 vector<string> strings;
594 explodeSubStrings(inStr, strings, -1);
596 if (strings.size()!=1)
597 throw ReadFightActionException("SEND_SELF_ACTION Needs 1 param");
599 NLMISC::CSheetId sheetId(strings[0].c_str());
600 if (sheetId==NLMISC::CSheetId::Unknown)
601 throw ReadFightActionException("SheetId Unknown "+inStr);
603 AISHEETS::IAIActionCPtr action = AISHEETS::CSheets::getInstance()->lookupAction(sheetId);
604 if (action.isNull())
605 throw ReadFightActionException("SheetId Unknown "+inStr);
607 return new CFightSendSelfAction(action, strings[0]);
610 std::string getName () const
612 return std::string("SEND_SELF_ACTION");
617 //////////////////////////////////////////////////////////////////////////
618 // AggroBlock
620 class CFightAggroBlock
621 :public CFightScriptComp
623 public:
624 CFightAggroBlock(const uint32 time):_Time(time)
627 virtual ~CFightAggroBlock()
629 bool update(CSpawnBot &bot) const
631 bot.blockAggro(_Time);
632 return true;
634 string toString() const
636 return "AGGRO_BLOCK("+NLMISC::toString(_Time/10)+")";
638 protected:
639 private:
640 uint32 _Time;
643 class CFightAggroBlockReader
644 :public CFightScriptCompReader
646 public:
647 CFightAggroBlockReader() {}
648 virtual ~CFightAggroBlockReader() {}
650 CFightScriptComp *create (const std::string &inStr)
652 vector<string> strings;
653 explodeSubStrings(inStr, strings, -1);
655 if (strings.size()!=1)
656 throw ReadFightActionException("AGGRO_BLOCK Needs 1 param");
658 uint32 time;
659 NLMISC::fromString(strings[0], time);
660 time *= 10;
661 return new CFightAggroBlock(time);
664 std::string getName () const
666 return std::string("AGGRO_BLOCK");
672 //////////////////////////////////////////////////////////////////////////
673 // AggroChange
675 class CFightAggroChange
676 :public CFightScriptComp
678 public:
679 CFightAggroChange()
682 virtual ~CFightAggroChange()
684 bool update(CSpawnBot &bot) const
686 CAIEntityPhysical *target=bot.getTarget();
687 if (!target)
688 return true;
690 bot.minimizeAggroFor(target->dataSetRow());
691 return true;
693 string toString() const
695 return "AGGRO_CHANGE()";
697 protected:
698 private:
701 class CFightAggroChangeReader
702 :public CFightScriptCompReader
704 public:
705 CFightAggroChangeReader() {}
706 virtual ~CFightAggroChangeReader() {}
708 CFightScriptComp *create (const std::string &inStr)
710 return new CFightAggroChange();
713 std::string getName () const
715 return std::string("AGGRO_CHANGE");
721 //////////////////////////////////////////////////////////////////////////
722 // DamageCoef
724 class CFightDamageCoef
725 :public CFightScriptComp
727 public:
728 CFightDamageCoef(const float coef) :_Coef(coef)
731 virtual ~CFightDamageCoef()
733 bool update(CSpawnBot &bot) const
735 bot._DamageCoef=_Coef;
736 return true;
738 string toString() const
740 return "DAMAGE_COEF("+NLMISC::toString(_Coef)+")";
742 protected:
743 private:
744 float _Coef;
747 class CFightDamageCoefReader
748 :public CFightScriptCompReader
750 public:
751 CFightDamageCoefReader() {}
752 virtual ~CFightDamageCoefReader() {}
754 CFightScriptComp *create (const std::string &inStr)
756 vector<string> strings;
757 explodeSubStrings(inStr, strings, -1);
759 if (strings.size()!=1)
760 throw ReadFightActionException("DAMAGE_COEF Needs 1 param");
762 const float coef=(float)atof(strings[0].c_str());
763 return new CFightDamageCoef(coef);
766 std::string getName () const
768 return std::string("DAMAGE_COEF");
775 //////////////////////////////////////////////////////////////////////////
776 // GroupDamageCoef
778 class CFightGroupDamageCoef
779 :public CFightScriptComp
781 public:
782 CFightGroupDamageCoef(const float coef) :_Coef(coef)
785 virtual ~CFightGroupDamageCoef()
787 bool update(CSpawnBot &bot) const
789 CSpawnGroup &spawnGroup=bot.spawnGrp();
790 CAliasCont<CBot> &bots=spawnGroup.getPersistent().bots();
792 float damageCoef=1.f;
793 for (sint32 nbRec=bots.size()-(spawnGroup.nbSpawnedBot()+spawnGroup.nbBotToDespawn());nbRec>=0;nbRec--)
794 damageCoef*=_Coef;
796 for (CCont<CBot>::iterator it=bots.begin(), itEnd=bots.end(); it!=itEnd; ++it)
798 CSpawnBot *spawnBot=it->getSpawnObj();
799 if (spawnBot)
800 spawnBot->_DamageCoef=damageCoef;
803 return true;
805 string toString() const
807 return "UPDATE_GROUP_DAMAGE_COEF("+NLMISC::toString(_Coef)+")";
809 protected:
810 private:
811 float _Coef;
814 class CFightGroupDamageCoefReader
815 :public CFightScriptCompReader
817 public:
818 CFightGroupDamageCoefReader() {}
819 virtual ~CFightGroupDamageCoefReader() {}
821 CFightScriptComp *create (const std::string &inStr)
823 vector<string> strings;
824 explodeSubStrings(inStr, strings, -1);
826 if (strings.size()!=1)
827 throw ReadFightActionException("UPDATE_GROUP_DAMAGE_COEF Needs 1 param");
829 const float coef=(float)atof(strings[0].c_str());
830 return new CFightGroupDamageCoef(coef);
833 std::string getName () const
835 return std::string("UPDATE_GROUP_DAMAGE_COEF");
841 //////////////////////////////////////////////////////////////////////////
842 // DamageSpeedCoef
844 class CFightDamageSpeedCoef
845 :public CFightScriptComp
847 public:
848 CFightDamageSpeedCoef(const float coef) :_Coef(coef)
851 virtual ~CFightDamageSpeedCoef()
853 bool update(CSpawnBot &bot) const
855 bot._DamageSpeedCoef=_Coef;
856 return true;
858 string toString() const
860 return "DAMAGE_SPEED_COEF("+NLMISC::toString(_Coef)+")";
862 protected:
863 private:
864 float _Coef;
867 class CFightDamageSpeedCoefReader
868 :public CFightScriptCompReader
870 public:
871 CFightDamageSpeedCoefReader() {}
872 virtual ~CFightDamageSpeedCoefReader() {}
874 CFightScriptComp *create (const std::string &inStr)
876 vector<string> strings;
877 explodeSubStrings(inStr, strings, -1);
879 if (strings.size()!=1)
880 throw ReadFightActionException("DAMAGE_SPEED_COEF Needs 1 param");
882 const float coef=(float)atof(strings[0].c_str());
883 return new CFightDamageSpeedCoef(coef);
886 std::string getName () const
888 return std::string("DAMAGE_SPEED_COEF");
893 //////////////////////////////////////////////////////////////////////////
894 // SetRandomTarget
896 class CFightSetRandomTarget
897 :public CFightScriptComp
899 public:
900 CFightSetRandomTarget(const float coef) :_Coef(coef)
903 virtual ~CFightSetRandomTarget()
905 bool update(CSpawnBot &bot) const
907 const CBotAggroOwner::TBotAggroList &list=bot.getBotAggroList();
908 size_t size = list.size();
909 if (size>0)
911 CBotAggroOwner::TBotAggroList::const_iterator it = list.begin();
912 for (size_t i=0; i<size; ++i)
913 ++it;
914 if (it!=list.end())
915 bot.maximizeAggroFor(it->first);
918 return true;
920 string toString() const
922 return "SET_RANDOM_TARGET()";
924 protected:
925 private:
926 float _Coef;
929 class CFightSetRandomTargetReader
930 :public CFightScriptCompReader
932 public:
933 CFightSetRandomTargetReader() {}
934 virtual ~CFightSetRandomTargetReader() {}
936 CFightScriptComp *create (const std::string &inStr)
938 vector<string> strings;
939 explodeSubStrings(inStr, strings, -1);
941 if ( strings.size()!=1
942 || strings[0]!="")
943 throw ReadFightActionException("SET_RANDOM_TARGET Needs 0 param");
945 const float coef=(float)atof(strings[0].c_str());
946 return new CFightSetRandomTarget(coef);
949 std::string getName () const
951 return std::string("SET_RANDOM_TARGET");
957 //////////////////////////////////////////////////////////////////////////
958 // Once
961 class CFightMult
962 :public CFightScriptComp
964 public:
965 CFightMult(const std::vector<CSmartPtr<CFightScriptComp> > &customComps)
966 :_CustomComps(customComps)
970 virtual ~CFightMult()
972 bool update (CSpawnBot &bot) const
974 for (uint32 i=0;i<_CustomComps.size();i++)
975 _CustomComps[i]->update(bot);
976 return true;
979 string toString() const
981 string outputString="MULT(";
983 for (uint32 i=0;i<_CustomComps.size();i++)
985 if (i>0)
986 outputString+=","; // add a "," to separate this param from previous ..
987 outputString+=_CustomComps[i]->toString();
990 return outputString+")";
993 protected:
994 private:
995 const std::vector<CSmartPtr<CFightScriptComp> > _CustomComps;
999 class CFightMultReader
1000 :public CFightScriptCompReader
1002 public:
1003 CFightMultReader() {}
1004 virtual ~CFightMultReader() {}
1006 CFightScriptComp *create (const std::string &inStr)
1008 vector<string> params;
1009 explodeSubStrings(inStr, params, -1);
1011 const uint32 nbSubScript=(uint32)params.size();
1013 std::vector<CSmartPtr<CFightScriptComp> > scriptComps;
1016 for (uint32 i=0;i<nbSubScript;i++)
1017 scriptComps.push_back(createScriptComp(params[i]));
1019 catch (const ReadFightActionException &ex)
1021 throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what()));
1023 return new CFightMult(scriptComps);
1025 std::string getName () const
1027 return std::string("MULT");
1032 //////////////////////////////////////////////////////////////////////////
1033 // CFightScript
1036 CFightScript::TFightScriptMap CFightScript::_ScriptCompList;
1038 CFightScript justInstanciatedToRegisterReaders;
1040 CFightScript::CFightScript()
1042 add(new CFightSelectFilterReader());
1044 add(new CFightMultReader());
1045 add(new CFightOnceReader());
1046 add(new CFightTimedFilterReader());
1047 add(new CFightRandomFilterReader());
1048 add(new CFightHPLessFilterReader());
1049 add(new CFightHPMoreFilterReader());
1051 add(new CFightAggroBlockReader());
1052 add(new CFightAggroChangeReader());
1053 add(new CFightDamageCoefReader());
1054 add(new CFightGroupDamageCoefReader());
1055 add(new CFightDamageSpeedCoefReader());
1056 add(new CFightSendActionReader());
1057 add(new CFightSendSelfActionReader());
1058 add(new CFightSetRandomTargetReader());
1061 void CFightScript::add(CFightScriptCompReader *reader)
1063 nlassert(reader!=NULL);
1064 nlassert(_ScriptCompList.find(reader->getName())==_ScriptCompList.end());
1065 _ScriptCompList.insert(std::make_pair(reader->getName(),reader));
1069 CFightScriptCompReader* CFightScriptCompReader::getScriptReader(const string &str)
1071 CFightScript::TFightScriptMap::iterator it=CFightScript::_ScriptCompList.find(str);
1072 if (it==CFightScript::_ScriptCompList.end())
1073 throw ReadFightActionException("Unknown ScriptComp "+str);
1075 return &(*(it->second));
1078 CFightScriptComp *CFightScriptCompReader::createScriptComp (const string &str)
1080 string scriptCompName;
1082 const string::size_type index=str.find_first_of("()", 0);
1083 if (index==string::npos)
1084 throw ReadFightActionException("ScriptComp Creation of :"+str+" Failed because of bad Syntax");
1085 scriptCompName=str.substr(0,index);
1090 return getScriptReader (scriptCompName)->create(str);
1092 catch (const ReadFightActionException &e)
1094 throw ReadFightActionException(string("ScriptComp creation failed : ")+string(e.what()));