Exemple #1
0
void Conversation::Restore( idRestoreGame *savefile ) {
	savefile->ReadString( _name );
	savefile->ReadBool( _isValid );
	savefile->ReadFloat( _talkDistance );
	int num;
	savefile->ReadInt( num );
	_actors.SetNum( num );
	for( int i = 0; i < num; i++ ) {
		savefile->ReadString( _actors[i] );
	}
	savefile->ReadInt( num );
	_commands.SetNum( num );
	for( int i = 0; i < num; i++ ) {
		_commands[i] = ConversationCommandPtr( new ConversationCommand );
		_commands[i]->Restore( savefile );
	}
	savefile->ReadInt( _currentCommand );
	savefile->ReadInt( _playCount );
	savefile->ReadInt( _maxPlayCount );
	savefile->ReadBool( _actorsMustBeWithinTalkDistance );
	savefile->ReadBool( _actorsAlwaysFaceEachOtherWhileTalking );
}
// Required entity visit function
void ConversationKeyExtractor::operator()(const std::string& key, const std::string& value) 
{
	// Quick discard of any non-conversation keys
	if (key.substr(0, 4) != "conv") return;

	// Extract the objective number
	static const std::regex reConvNum("conv_(\\d+)_(.*)");
	std::smatch results;
	int iNum;

	if (!std::regex_match(key, results, reConvNum)) {
		// No match, abort
		return;
	}

	// Get the conversation number
	iNum = 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[iNum].name = value;
	}
	else if (convSubString == "talk_distance") {
		_convMap[iNum].talkDistance = string::convert<float>(value, 60);
	}
	else if (convSubString == "actors_must_be_within_talkdistance") {
		_convMap[iNum].actorsMustBeWithinTalkdistance = (value == "1");
	}
	else if (convSubString == "actors_always_face_each_other_while_talking") {
		_convMap[iNum].actorsAlwaysFaceEachOther = (value == "1");
	}
	else if (convSubString == "max_play_count") {
		_convMap[iNum].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[iNum].actors.insert(Conversation::ActorMap::value_type(actorNum, value));
	}
	else if (convSubString.substr(0, 4) == "cmd_") {
		// This is a conversation command, form a new regex
		static const std::regex reCommand("cmd_(\\d+)_(.*)");
		std::smatch cmdResults;

		if (!std::regex_match(convSubString, cmdResults, reCommand)) {
			return; // not matching
		}

		int cmdIndex = string::convert<int>(cmdResults[1].str());
		std::string cmdSubStr = cmdResults[2];

		ConversationCommandPtr command;
		Conversation::CommandMap::iterator found = _convMap[iNum].commands.find(cmdIndex);

		if (found != _convMap[iNum].commands.end()) {
			// Command already exists
			command = found->second;
		}
		else {
			// Command with the given index does not exist yet, create it
			command = ConversationCommandPtr(new ConversationCommand);

			// Insert this into the map
			_convMap[iNum].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;
		}
	}
}