Dialogue merging

This commit is contained in:
scrawl 2014-02-20 16:59:20 +01:00
parent 5b76c0893a
commit 1677fcf324
9 changed files with 62 additions and 19 deletions

View file

@ -651,7 +651,7 @@ void Record<ESM::Dialogue>::print()
// Sadly, there are no DialInfos, because the loader dumps as it // Sadly, there are no DialInfos, because the loader dumps as it
// loads, rather than loading and then dumping. :-( Anyone mind if // loads, rather than loading and then dumping. :-( Anyone mind if
// I change this? // I change this?
std::vector<ESM::DialInfo>::iterator iit; ESM::Dialogue::InfoContainer::iterator iit;
for (iit = mData.mInfo.begin(); iit != mData.mInfo.end(); iit++) for (iit = mData.mInfo.begin(); iit != mData.mInfo.end(); iit++)
std::cout << "INFO!" << iit->mId << std::endl; std::cout << "INFO!" << iit->mId << std::endl;
} }

View file

@ -289,7 +289,7 @@ namespace MWDialogue
// Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group, // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group,
// in which case it should not be added to the journal. // in which case it should not be added to the journal.
for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin(); for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin();
iter!=dialogue.mInfo.end(); ++iter) iter!=dialogue.mInfo.end(); ++iter)
{ {
if (iter->mId == info->mId) if (iter->mId == info->mId)
@ -467,7 +467,7 @@ namespace MWDialogue
// Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group, // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group,
// in which case it should not be added to the journal. // in which case it should not be added to the journal.
for (std::vector<ESM::DialInfo>::const_iterator iter = mDialogueMap[mLastTopic].mInfo.begin(); for (ESM::Dialogue::InfoContainer::const_iterator iter = mDialogueMap[mLastTopic].mInfo.begin();
iter!=mDialogueMap[mLastTopic].mInfo.end(); ++iter) iter!=mDialogueMap[mLastTopic].mInfo.end(); ++iter)
{ {
if (iter->mId == info->mId) if (iter->mId == info->mId)

View file

@ -621,7 +621,7 @@ std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue
bool infoRefusal = false; bool infoRefusal = false;
// Iterate over topic responses to find a matching one // Iterate over topic responses to find a matching one
for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin(); for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin();
iter!=dialogue.mInfo.end(); ++iter) iter!=dialogue.mInfo.end(); ++iter)
{ {
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter)) if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
@ -646,7 +646,7 @@ std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue
const ESM::Dialogue& infoRefusalDialogue = *dialogues.find ("Info Refusal"); const ESM::Dialogue& infoRefusalDialogue = *dialogues.find ("Info Refusal");
for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin(); for (ESM::Dialogue::InfoContainer::const_iterator iter = infoRefusalDialogue.mInfo.begin();
iter!=infoRefusalDialogue.mInfo.end(); ++iter) iter!=infoRefusalDialogue.mInfo.end(); ++iter)
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter, invertDisposition)) { if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter, invertDisposition)) {
infos.push_back(&*iter); infos.push_back(&*iter);
@ -660,7 +660,7 @@ std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue
bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const
{ {
for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin(); for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin();
iter!=dialogue.mInfo.end(); ++iter) iter!=dialogue.mInfo.end(); ++iter)
{ {
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter)) if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))

View file

@ -20,7 +20,7 @@ namespace MWDialogue
const ESM::Dialogue *dialogue = const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (topic); MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (topic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin()); for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter) iter!=dialogue->mInfo.end(); ++iter)
if (iter->mId == mInfoId) if (iter->mId == mInfoId)
{ {
@ -73,7 +73,7 @@ namespace MWDialogue
const ESM::Dialogue *dialogue = const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (topic); MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (topic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin()); for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter) iter!=dialogue->mInfo.end(); ++iter)
if (iter->mData.mDisposition==index) /// \todo cleanup info structure if (iter->mData.mDisposition==index) /// \todo cleanup info structure
{ {

View file

@ -56,7 +56,7 @@ namespace MWDialogue
if (infoId.empty()) if (infoId.empty())
return true; return true;
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin()); for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter) iter!=dialogue->mInfo.end(); ++iter)
if (iter->mId == infoId) if (iter->mId == infoId)
return true; return true;

View file

@ -27,7 +27,7 @@ namespace MWDialogue
const ESM::Dialogue *dialogue = const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (mTopic); MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin()); for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter) iter!=dialogue->mInfo.end(); ++iter)
if (iter->mQuestStatus==ESM::DialInfo::QS_Name) if (iter->mQuestStatus==ESM::DialInfo::QS_Name)
return iter->mResponse; return iter->mResponse;
@ -45,7 +45,7 @@ namespace MWDialogue
const ESM::Dialogue *dialogue = const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (mTopic); MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin()); for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter) iter!=dialogue->mInfo.end(); ++iter)
if (iter->mData.mDisposition==index && iter->mQuestStatus!=ESM::DialInfo::QS_Name) if (iter->mData.mDisposition==index && iter->mQuestStatus!=ESM::DialInfo::QS_Name)
{ {
@ -53,8 +53,6 @@ namespace MWDialogue
mFinished = true; mFinished = true;
else if (iter->mQuestStatus==ESM::DialInfo::QS_Restart) else if (iter->mQuestStatus==ESM::DialInfo::QS_Restart)
mFinished = false; mFinished = false;
// Don't return here. Quest status may actually be in a different info record, since we don't merge these (yet?)
} }
// The index must be set even if no related journal entry was found // The index must be set even if no related journal entry was found
@ -73,7 +71,7 @@ namespace MWDialogue
const ESM::Dialogue *dialogue = const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (entry.mTopic); MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (entry.mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin()); for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter) iter!=dialogue->mInfo.end(); ++iter)
if (iter->mId == entry.mInfoId) if (iter->mId == entry.mInfoId)
{ {

View file

@ -72,9 +72,10 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
if (n.val == ESM::REC_INFO) { if (n.val == ESM::REC_INFO) {
std::string id = esm.getHNOString("INAM"); std::string id = esm.getHNOString("INAM");
if (dialogue) { if (dialogue) {
dialogue->mInfo.push_back(ESM::DialInfo()); ESM::DialInfo info;
dialogue->mInfo.back().mId = id; info.mId = id;
dialogue->mInfo.back().load(esm); info.load(esm);
dialogue->addInfo(info, esm.getIndex() != 0);
} else { } else {
std::cerr << "error: info record without dialog" << std::endl; std::cerr << "error: info record without dialog" << std::endl;
esm.skipRecord(); esm.skipRecord();

View file

@ -1,5 +1,7 @@
#include "loaddial.hpp" #include "loaddial.hpp"
#include <iostream>
#include "esmreader.hpp" #include "esmreader.hpp"
#include "esmwriter.hpp" #include "esmwriter.hpp"
#include "defs.hpp" #include "defs.hpp"
@ -43,4 +45,40 @@ void Dialogue::save(ESMWriter &esm) const
mInfo.clear(); mInfo.clear();
} }
void Dialogue::addInfo(const ESM::DialInfo& info, bool merge)
{
// TODO: use std::move
if (!merge || mInfo.empty() || info.mNext.empty())
{
mInfo.push_back(info);
return;
}
if (info.mPrev.empty())
{
mInfo.push_front(info);
return;
}
int i=0;
for (ESM::Dialogue::InfoContainer::iterator it = mInfo.begin(); it != mInfo.end(); ++it)
{
if (info.mPrev == it->mId)
{
mInfo.insert(++it, info);
return;
}
if (info.mNext == it->mId)
{
mInfo.insert(it, info);
return;
}
if (info.mId == it->mId)
{
*it = info;
return;
}
++i;
}
std::cerr << "Failed to insert info " << info.mId << std::endl;
}
} }

View file

@ -2,7 +2,7 @@
#define OPENMW_ESM_DIAL_H #define OPENMW_ESM_DIAL_H
#include <string> #include <string>
#include <vector> #include <list>
#include "loadinfo.hpp" #include "loadinfo.hpp"
@ -33,11 +33,17 @@ struct Dialogue
std::string mId; std::string mId;
signed char mType; signed char mType;
std::vector<DialInfo> mInfo;
typedef std::list<DialInfo> InfoContainer;
InfoContainer mInfo;
void load(ESMReader &esm); void load(ESMReader &esm);
void save(ESMWriter &esm) const; void save(ESMWriter &esm) const;
/// @param merge Merge with existing list, or just push each record to the end of the list?
void addInfo (const ESM::DialInfo& info, bool merge);
void blank(); void blank();
///< Set record to default state (does not touch the ID and does not change the type). ///< Set record to default state (does not touch the ID and does not change the type).
}; };