// 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 "npc_description_msg.h" #include "ai.h" #include "ai_instance.h" #include "ai_mgr.h" #include "game_share/pvp_clan.h" using namespace std; using namespace NLMISC; CNpcChatProfileImp::CNpcChatProfileImp(const CNpcChatProfileImp &other0,const CNpcChatProfileImp &other1) : CNpcChatProfile(static_cast(other0), static_cast(other1)) {} CNpcChatProfileImp CNpcChatProfileImp::combineChatProfile(const CNpcChatProfileImp &referenceChat, const CNpcChatProfileImp ¤tChat) { CNpcChatProfileImp newProfile; { newProfile._ExplicitSales = referenceChat._ExplicitSales; // vector< RYMSG::TExplicitSale >::const_iterator first(referenceChat._ExplicitSales.begin()), last(referenceChat._ExplicitSales.end()); // for (; first != last; ++first) // { //// if (find(currentChat._shopItemTypesNegators.begin(), currentChat._shopItemTypesNegators.end(), *first) == currentChat._shopItemTypesNegators.end()) //// { // // also check quality //// uint index = first - referenceChat._shopItemTypes.begin(); //// uint32 quality = referenceChat._shopItemQualities[index]; //// if (find(currentChat._shopItemQualitiesNegators.begin(), currentChat._shopItemQualitiesNegators.end(), quality) == currentChat._shopItemQualitiesNegators.end()) //// { // newProfile._ExplicitSales.push_back(first); // newProfile._shopItemTypes.push_back(*first); // newProfile._shopItemQualities.push_back(currentChat._shopItemQualities[index]); // newProfile._shopItemPrices.push_back(currentChat._shopItemPrices[index]); // newProfile._shopItemFactionTypes.push_back(currentChat._shopItemFactionTypes[index]); // newProfile._shopItemFactionPointPrices.push_back(currentChat._shopItemFactionPointPrices[index]); //// } //// } // } } { newProfile._ShopTypes = referenceChat._ShopTypes; // std::vector::const_iterator first(referenceChat._shopTypes.begin()), last(referenceChat._shopTypes.end()); // for (; first != last; ++first) // { //// if (find(currentChat._shopTypesNegators.begin(), currentChat._shopTypesNegators.end(), *first) == currentChat._shopTypesNegators.end()) //// { // newProfile._shopTypes.push_back(*first); //// } // } } { newProfile._Missions = referenceChat._Missions; // std::vector::const_iterator first(referenceChat._missions.begin()), last(referenceChat._missions.end()); // for (; first != last; ++first) // { //// if (find(currentChat._missionsNegators.begin(), currentChat._missionsNegators.end(), *first) == currentChat._missionsNegators.end()) //// { // newProfile._missions.push_back(*first); //// } // } } // this properties are read from current chat profile... newProfile._CellZones = currentChat._CellZones; newProfile._NewsChannels = currentChat._NewsChannels; // newProfile._GuildCreator = currentChat._GuildCreator; newProfile._WelcomePhrase = currentChat._WelcomePhrase; newProfile._WebPage = currentChat._WebPage; newProfile._WebPageName = currentChat._WebPageName; // newProfile._ExplicitActionTradeList = currentChat._ExplicitActionTradeList; newProfile._FilterExplicitActionTradeByPlayerRace = currentChat._FilterExplicitActionTradeByPlayerRace; newProfile._ExplicitActionSPType = currentChat._ExplicitActionSPType; newProfile._FilterExplicitActionTradeByBotRace = currentChat._FilterExplicitActionTradeByBotRace; // this properties are directly merged newProfile._OptionalProperties = referenceChat._OptionalProperties; newProfile._OptionalProperties.insert(newProfile._OptionalProperties.end(), currentChat._OptionalProperties.begin(), currentChat._OptionalProperties.end()); return newProfile; } //--------------------------------------------------------------------------------------- // Management of shop type names //--------------------------------------------------------------------------------------- static std::vector ShopTypeNames; static std::map ShopNameAliases; // try to add an entry corresponding to shop name 'name' to vector 'shopList' static bool LookupShopType(std::string name,std::vector &shopList) { static bool init=false; // if this is the first call to the routine go and read the config file that contains the shop list if (!init) { init=true; try { NLMISC::CConfigFile ShopConfigFile; const string path = NLMISC::CPath::lookup( "shop_category.cfg", false, true, true ); if (path.empty()) return false; ShopConfigFile.load( path ); // read the vector of shop names (in their long hand format) CConfigFile::CVar& cvShopType = ShopConfigFile.getVar("ShopCategory"); uint i; for ( i=0; i < cvShopType.size(); ++i ) { if ( cvShopType.asString(i) != "" ) { // make sure the string doesn't turn up more than once in input data for (uint j=0;j shop_category.cfg or ShopCategory not found, no shop base type intialized..."); } } // deal with multi-part strings std::string clause,tail; AI_SHARE::stringToKeywordAndTail(name,clause,tail); if (!tail.empty()) { bool result=true; do { result = LookupShopType(clause,shopList) && result; } while (result && AI_SHARE::stringToKeywordAndTail(tail,clause,tail)); return result; } // lookup the name in the alias map - if found use the alias (may be multi-part) if (ShopNameAliases.find(name)!=ShopNameAliases.end()) return LookupShopType(ShopNameAliases[name],shopList); // look through the names vector for a name match for (uint i=0;i &ShopCategories, const std::vector &ItemTypesForSale, const std::vector &MissionIds) { std::string s; if (!ShopCategories.empty()) { if (ShopCategories[0]>=ShopTypeNames.size()) s+="shopTypes(ERROR"; else s+=NLMISC::toString(" shopTypes(%s",ShopTypeNames[ShopCategories[0]].c_str()); for (uint i=1;i=ShopTypeNames.size()) s+=",ERROR"; else s+=NLMISC::toString(",%s",ShopTypeNames[ShopCategories[i]].c_str()); } s+=")"; } if (!ItemTypesForSale.empty()) { s+=NLMISC::toString(" shopTypes(%u",ItemTypesForSale[0].toString().c_str()); for (uint i=1;i priceInfos; CVectorSString parts; tail.splitBySeparator(';', parts); RYMSG::TExplicitSale sale; // read the parts for (uint i=0; ifindMissionAlias(_missionsNegators, tail); // // if (_missionsNegators.empty()) // nlwarning("Can't found alias for mission '%s' !", tail.c_str()); // // return true; // } // welcome message if (NLMISC::nlstricmp(keyword, "welcome")==0) { if (!_WelcomePhrase.empty()) nlwarning("Welcome phrase ('%s') already set in chat ! Overwriting with '%s'", _WelcomePhrase.c_str(), tail.c_str()); _WelcomePhrase = tail; } // web page if (NLMISC::nlstricmp(keyword, "web")==0) { if (!_WebPage.empty()) nlwarning("Web Page ('%s') already set in chat ! Overwriting with '%s'", _WebPage.c_str(), tail.c_str()); // split to webpage name and the true webpage _WebPageName.clear(); AI_SHARE::stringToWordAndTail(tail, _WebPageName, tail); _WebPage = tail; } // guild creator if (NLMISC::nlstricmp(keyword, "guild")==0) { BOMB("No more supported option", return false); // _GuildCreator = tail == "true" || tail == "1" || tail =="on"; // return true; } // dynamic mission cell zones names if (NLMISC::nlstricmp(keyword, "dyn_mis") == 0) { string word; while (AI_SHARE::stringToWordAndTail(tail, word, tail)) { _CellZones.push_back(word); } _DynamicMissionGiver = true; return true; } // news channel names if (NLMISC::nlstricmp(keyword, "news") == 0) { string word; while (AI_SHARE::stringToWordAndTail(tail, word, tail)) { _NewsChannels.push_back(word); } if (_NewsChannels.empty()) { // no channels name, push an empty string to tag that we must use the local info channel (ie outpost or sector) _NewsChannels.push_back(string()); } return true; } // context menu entry if (NLMISC::nlstricmp(keyword, "menu") == 0) { string title; while (AI_SHARE::stringToWordAndTail(tail, title, tail)) { string detail; if (!AI_SHARE::stringToWordAndTail(tail, detail, tail)) { nlwarning("Mission detail string ID in 'menu' entry for title '%s'", title.c_str()); return false; } RYMSG::TContextOption co; co.setTitle(title); co.setDetail(detail); _ContextOptions.push_back(co); } return true; } // outpost entry if (NLMISC::nlstricmp(keyword, "outpost") == 0) { string word; while (AI_SHARE::stringToWordAndTail(tail, word, tail)) { _Outpost = NLMISC::CSheetId(word+".outpost"); } return true; } // if no match found throw an error return false; } void TGenNpcDescMsgImp::setChat(const CNpcChatProfileImp& chatProfile) { _MissionIds = chatProfile.getMissions(); _ExplicitSales = chatProfile.getExplicitSales(); // ItemTypesForSale = chatProfile.getShopItemTypes(); // ItemQualitiesForSale = chatProfile.getShopItemQualities(); // ItemPrices = chatProfile.getShopItemPrices(); // ItemFactionType = chatProfile.getShopItemFactionTypes(); // ItemFactionPointPrice = chatProfile.getShopItemFactionPointPrices(); _ShopCategories = chatProfile.getShopTypes(); // NamedItemName = chatProfile.getShopNamedItemNames(); // NamedItemPrice = chatProfile.getShopNamedItemPrices(); // NamedItemFactionType = chatProfile.getShopNamedItemFactionTypes(); // NamedItemFactionPointPrice = chatProfile.getShopNamedItemFactionPointPrices(); // ExplicitActionTradeList = chatProfile.getExplicitActionTradeList(); _FilterExplicitActionTradeByPlayerRace = chatProfile.getFilterExplicitActionTradeByPlayerRace(); _ExplicitActionSPType = chatProfile.getExplicitActionSPType(); _FilterExplicitActionTradeByBotRace = chatProfile.getFilterExplicitActionTradeByBotRace(); _WelcomePhrase = chatProfile.getWelcomePhrase(); _WebPage = chatProfile.getWebPage(); _WebPageName = chatProfile.getWebPageName(); // _GuildCreator = chatProfile.getGuildCreator() (); _DynamicMissionGiver = chatProfile.getDynamicMissionGiver(); //!chatProfile.getCellZones().empty(); _NewsChannels = chatProfile.getNewsChannels(); _ContextOptions = chatProfile.getContextOptions(); // ContextOptionsTitles = chatProfile.getContextOptionsTitles(); // ContextOptionsDetails = chatProfile.getContextOptionsDetails(); // As I don't remembre why I did an insert instead of an affectation I let it commented here. // vector const& chatOptionalProperties = chatProfile.getOptionalProperties(); // OptionalProperties.insert(OptionalProperties.end(), chatOptionalProperties.begin(), chatOptionalProperties.end()); _OptionalProperties = chatProfile.getOptionalProperties(); _Outpost = chatProfile.getOutpost(); }