1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
#include "ConversationKeyExtractor.h"
#include "itextstream.h"
#include <regex>
#include "string/convert.h"
#include "string/predicate.h"
#include "ConversationCommand.h"
#include "ConversationCommandLibrary.h"
namespace conversation
{
ConversationKeyExtractor::ConversationKeyExtractor(ConversationMap& map) :
_convMap(map),
_regexConvNum("conv_(\\d+)_(.*)"),
_regexConvCmd("cmd_(\\d+)_(.*)")
{
assert(_convMap.empty());
}
void ConversationKeyExtractor::operator()(const std::string& key, const std::string& value)
{
// Quick discard of any non-conversation keys
if (!string::starts_with(key, "conv")) return;
// Extract the conv index
std::smatch results;
if (!std::regex_match(key, results, _regexConvNum))
{
// No match, abort
return;
}
// Get the conversation number
int num = string::convert<int>(results[1].str());
// We now have the conversation number and the substring (everything after
// "conv_<n>_" which applies to this conversation.
std::string convSubString = results[2];
// Switch on the substring
if (convSubString == "name")
{
_convMap[num].name = value;
}
else if (convSubString == "talk_distance")
{
_convMap[num].talkDistance = string::convert<float>(value, 60);
}
else if (convSubString == "actors_must_be_within_talkdistance")
{
_convMap[num].actorsMustBeWithinTalkdistance = (value == "1");
}
else if (convSubString == "actors_always_face_each_other_while_talking")
{
_convMap[num].actorsAlwaysFaceEachOther = (value == "1");
}
else if (convSubString == "max_play_count")
{
_convMap[num].maxPlayCount = string::convert<int>(value, -1);
}
else if (convSubString.substr(0, 6) == "actor_")
{
// This is an actor definition, extract the number
int actorNum = string::convert<int>(convSubString.substr(6), -1);
if (actorNum == -1)
{
return;
}
// Store the actor in the map
_convMap[num].actors.emplace(actorNum, value);
}
else if (convSubString.substr(0, 4) == "cmd_")
{
// This is a conversation command
std::smatch cmdResults;
if (!std::regex_match(convSubString, cmdResults, _regexConvCmd))
{
return; // not matching
}
int cmdIndex = string::convert<int>(cmdResults[1].str());
std::string cmdSubStr = cmdResults[2];
ConversationCommandPtr command;
auto found = _convMap[num].commands.find(cmdIndex);
if (found != _convMap[num].commands.end())
{
// Command already exists
command = found->second;
}
else
{
// Command with the given index does not exist yet, create it
command = std::make_shared<ConversationCommand>();
// Insert this into the map
_convMap[num].commands[cmdIndex] = command;
}
if (cmdSubStr == "type")
{
try
{
command->type = ConversationCommandLibrary::Instance().findCommandInfo(value).id;
}
catch (std::runtime_error& e)
{
rError() << e.what() << std::endl;
return;
}
}
else if (cmdSubStr == "actor")
{
command->actor = string::convert<int>(value);
}
else if (cmdSubStr == "wait_until_finished")
{
command->waitUntilFinished = (value == "1");
}
else if (cmdSubStr.substr(0,4) == "arg_")
{
int cmdArgIndex = string::convert<int>(cmdSubStr.substr(4));
command->arguments[cmdArgIndex] = value;
}
}
}
} // namespace conversation
|