// Ryzom - MMORPG Framework // 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 . #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 &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 params; explodeSubStrings(inStr, params, -1); if (params.size()!=2) throw ReadFightActionException("SELECT Needs 2 Params: ,"); CSmartPtr scriptComp; try { scriptComp=createScriptComp(params[1]); } catch (const 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 _CustomComp; }; class CFightOnceReader :public CFightScriptCompReader { public: CFightOnceReader() {} virtual ~CFightOnceReader() {} CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException) { vector params; explodeSubStrings(inStr, params, -1); if (params.size()!=1) throw ReadFightActionException("ONCE Needs 1 Param: "); CSmartPtr scriptComp; try { scriptComp=createScriptComp(params[0]); } catch (const 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()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 _CustomComp; uint32 _DeltaTime; }; class CFightTimedFilterReader :public CFightScriptCompReader { public: CFightTimedFilterReader() {} virtual ~CFightTimedFilterReader() {} CFightScriptComp *create (const std::string &inStr) throw (ReadFightActionException) { vector params; explodeSubStrings(inStr, params, -1); if (params.size()!=2) throw ReadFightActionException("EVERY_SEC Needs 2 Params: