From 085cead1a11dd6afc33ae7ed40cbe7319bc079c6 Mon Sep 17 00:00:00 2001 From: Ulukyn Date: Wed, 4 Mar 2020 01:02:52 +0100 Subject: [PATCH] Merge branch 'ark' --- .../mission_manager/mission_manager.cpp | 24 +++++++++++++++++++ .../mission_manager/missions_commands.cpp | 15 ++++++++++++ .../player_manager/character.cpp | 4 +++- .../player_manager/character.h | 2 +- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp b/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp index 7764cdb95..542a90a25 100644 --- a/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp +++ b/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp @@ -1405,6 +1405,28 @@ void CMissionManager::removeAllUserDynChat(CCharacter * user) user->processMissionEvent(event,aliases[i] ); } +void CMissionManager::processMissionsEventEndDynChat(CCharacter * user) +{ + // we first close all the concerned dyn chat interface on the client,then send EndDynchat event and finally remove the concerned entries from the map + // we have to do it in three passes because processMissionEvent can remove dyn chat entries. And we'd better avoid dereferencement on invalid iterators... + nlassert(user); + vector aliases; + // close all interfaces + CHashMultiMap::iterator it = _DynChats.find( user->getEntityRowId() ); + for (; it!= _DynChats.end() && (*it).first == user->getEntityRowId(); ++it ) + { + aliases.push_back((*it).second.Mission->getTemplateId()); + } + + // For each concerned mission, send an end dyn chat event to the player, specifying the mission + // This must be after _DynChats.erase(user->getEntityRowId()), otherwise the event (e.g. jump + // back) can trigger a openDynChat() on the same bot that would lead to a reentrance bug. + CMissionEventEndDynChat event; + const uint eventCount = (uint)aliases.size(); + for ( uint i = 0; i < eventCount; ++i ) + user->processMissionEvent(event,aliases[i] ); +} + void CMissionManager::removeMissionDynChat(CCharacter * user, CMission * instance) { nlassert(user); @@ -1495,6 +1517,7 @@ void CMissionManager::dynChatChoice( CCharacter * user, const TDataSetRow & botR uint i = 0; uint nbJumpPoints = (uint)templ->JumpPoints.size(); bool updateJournal = false; + nlinfo("nbJumpPoints = %d", nbJumpPoints); for (; i < nbJumpPoints; i++ ) { if ( templ->JumpPoints[i].Name == jump ) @@ -1503,6 +1526,7 @@ void CMissionManager::dynChatChoice( CCharacter * user, const TDataSetRow & botR closeDynChat( user, botRow ); std::list< CMissionEvent * > eventList; + nlinfo("Jump to %d", i); inst->jump( templ->JumpPoints[i].Step,templ->JumpPoints[i].Action,eventList ); // Send to AIS (to stop the bot). Important: there must be the same number of items pushed in DynChatEnd that in DynChatStart for the bot to resume. diff --git a/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp b/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp index 52a3bd40e..c4d5dccd1 100644 --- a/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp +++ b/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp @@ -4153,8 +4153,23 @@ NLMISC_COMMAND(startMoveBot,"start move bot or previous stopped bot"," [< CharacterBotChatBeginEnd.BotChatEnd.push_back(TargetRowId); log.displayNL("OK"); + return true; } +NLMISC_COMMAND(closeDynChat, "close DynChat", " ") +{ + if (args.size() < 1) return false; + + GET_ACTIVE_CHARACTER + + bool processMissions = true; + if (args.size() >= 2 && (args[1] == "false" || args[1] == "0")) + processMissions = false; + + c->endBotChat(false, false, processMissions); + + return true; +} NLMISC_COMMAND(manageBuilding, "Manage a building", " ") { diff --git a/ryzom/server/src/entities_game_service/player_manager/character.cpp b/ryzom/server/src/entities_game_service/player_manager/character.cpp index 0fef6abce..bb94e2772 100644 --- a/ryzom/server/src/entities_game_service/player_manager/character.cpp +++ b/ryzom/server/src/entities_game_service/player_manager/character.cpp @@ -12206,7 +12206,7 @@ CCreature* CCharacter::startBotChat(BOTCHATTYPE::TBotChatFlags chatType) // endBotChat // //----------------------------------------------- -void CCharacter::endBotChat(bool newBotChat, bool closeDynChat) +void CCharacter::endBotChat(bool newBotChat, bool closeDynChat, bool processMissions) { _TradePagesToUpdate.clear(); @@ -12243,6 +12243,8 @@ void CCharacter::endBotChat(bool newBotChat, bool closeDynChat) if (closeDynChat) CMissionManager::getInstance()->removeAllUserDynChat(this); + else if (processMissions) + CMissionManager::getInstance()->processMissionsEventEndDynChat(this); } // Inform AI about bot chat end diff --git a/ryzom/server/src/entities_game_service/player_manager/character.h b/ryzom/server/src/entities_game_service/player_manager/character.h index b66c932a3..d93383dfb 100644 --- a/ryzom/server/src/entities_game_service/player_manager/character.h +++ b/ryzom/server/src/entities_game_service/player_manager/character.h @@ -1175,7 +1175,7 @@ public: /// end the bot chat. newBotChat must be set to true if the chat is canceled because of another bot chat. /// closeDynChat must be true to close the current dynChat - void endBotChat(bool newBotChat = false, bool closeDynChat = false); + void endBotChat(bool newBotChat = false, bool closeDynChat = false, bool processMissions = false); /// return the current bot chat type uint8 getBotChatType() const;