Implement ClearInfoActor script instruction (Fixes #1422)

deque
scrawl 11 years ago
parent a90245147b
commit 2dd54dbcfc

@ -76,6 +76,9 @@ namespace MWBase
/// @return faction1's opinion of faction2
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const = 0;
/// Removes the last added topic response for the given actor from the journal
virtual void clearInfoActor (const MWWorld::Ptr& actor) const = 0;
};
}

@ -60,6 +60,11 @@ namespace MWBase
///< Get the journal index.
virtual void addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) = 0;
/// \note topicId must be lowercase
virtual void removeLastAddedTopicResponse (const std::string& topicId, const std::string& actorName) = 0;
///< Removes the last topic response added for the given topicId and actor name.
/// \note topicId must be lowercase
virtual TEntryIter begin() const = 0;
///< Iterator pointing to the begin of the main journal.

@ -698,6 +698,15 @@ namespace MWDialogue
return diff;
}
void DialogueManager::clearInfoActor(const MWWorld::Ptr &actor) const
{
if (actor == mActor && !mLastTopic.empty())
{
MWBase::Environment::get().getJournal()->removeLastAddedTopicResponse(
mLastTopic, actor.getClass().getName(actor));
}
}
std::vector<HyperTextToken> ParseHyperText(const std::string& text)
{
std::vector<HyperTextToken> result;

@ -40,7 +40,7 @@ namespace MWDialogue
bool mTalkedTo;
int mChoice;
std::string mLastTopic;
std::string mLastTopic; // last topic ID, lowercase
bool mIsInChoice;
float mTemporaryDispositionChange;
@ -99,6 +99,9 @@ namespace MWDialogue
/// @return faction1's opinion of faction2
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const;
/// Removes the last added topic response for the given actor from the journal
virtual void clearInfoActor (const MWWorld::Ptr& actor) const;
};

@ -113,6 +113,16 @@ namespace MWDialogue
topic.addEntry (entry);
}
void Journal::removeLastAddedTopicResponse(const std::string &topicId, const std::string &actorName)
{
Topic& topic = getTopic (topicId);
topic.removeLastAddedResponse(actorName);
if (topic.begin() == topic.end())
mTopics.erase(mTopics.find(topicId)); // All responses removed -> remove topic
}
int Journal::getJournalIndex (const std::string& id) const
{
TQuestContainer::const_iterator iter = mQuests.find (id);

@ -39,6 +39,11 @@ namespace MWDialogue
///< Get the journal index.
virtual void addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor);
/// \note topicId must be lowercase
virtual void removeLastAddedTopicResponse (const std::string& topicId, const std::string& actorName);
///< Removes the last topic response added for the given topicId and actor name.
/// \note topicId must be lowercase
virtual TEntryIter begin() const;
///< Iterator pointing to the begin of the main journal.

@ -58,4 +58,17 @@ namespace MWDialogue
{
return mEntries.end();
}
void Topic::removeLastAddedResponse (const std::string& actorName)
{
for (std::vector<MWDialogue::Entry>::reverse_iterator it = mEntries.rbegin();
it != mEntries.rend(); ++it)
{
if (it->mActorName == actorName)
{
mEntries.erase( (++it).base() ); // erase doesn't take a reverse_iterator
return;
}
}
}
}

@ -48,6 +48,8 @@ namespace MWDialogue
virtual std::string getName() const;
void removeLastAddedResponse (const std::string& actorName);
TEntryIter begin() const;
///< Iterator pointing to the begin of the journal for this topic.

@ -235,6 +235,18 @@ namespace MWScript
}
};
template <class R>
class OpClearInfoActor : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWBase::Environment::get().getDialogueManager()->clearInfoActor(ptr);
}
};
void installOpcodes (Interpreter::Interpreter& interpreter)
{
@ -256,6 +268,8 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFactionExplicit, new OpSameFaction<ExplicitRef>);
interpreter.installSegment5 (Compiler::Dialogue::opcodeModFactionReaction, new OpModFactionReaction);
interpreter.installSegment5 (Compiler::Dialogue::opcodeGetFactionReaction, new OpGetFactionReaction);
interpreter.installSegment5 (Compiler::Dialogue::opcodeClearInfoActor, new OpClearInfoActor<ImplicitRef>);
interpreter.installSegment5 (Compiler::Dialogue::opcodeClearInfoActorExplicit, new OpClearInfoActor<ExplicitRef>);
}
}

@ -393,5 +393,7 @@ op 0x2000241: onKnockoutExplicit
op 0x2000242: ModFactionReaction
op 0x2000243: GetFactionReaction
op 0x2000244: Activate, explicit
op 0x2000245: ClearInfoActor
op 0x2000246: ClearInfoActor, explicit
opcodes 0x2000245-0x3ffffff unused
opcodes 0x2000247-0x3ffffff unused

@ -181,6 +181,7 @@ namespace Compiler
opcodeSameFactionExplicit);
extensions.registerInstruction("modfactionreaction", "ccl", opcodeModFactionReaction);
extensions.registerFunction("getfactionreaction", 'l', "ccl", opcodeGetFactionReaction);
extensions.registerInstruction("clearinfoactor", "", opcodeClearInfoActor, opcodeClearInfoActorExplicit);
}
}

@ -154,6 +154,8 @@ namespace Compiler
const int opcodeSameFactionExplicit = 0x20001b6;
const int opcodeModFactionReaction = 0x2000242;
const int opcodeGetFactionReaction = 0x2000243;
const int opcodeClearInfoActor = 0x2000245;
const int opcodeClearInfoActorExplicit = 0x2000246;
}
namespace Gui

Loading…
Cancel
Save