Skip to content

Commit

Permalink
AURORA: Add DLGFile abilities to read and use script parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
Nostritius committed Oct 14, 2019
1 parent 7d3860c commit 0b53173
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 28 deletions.
69 changes: 52 additions & 17 deletions src/aurora/dlgfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <cassert>

#include "src/common/strutil.h"
#include "src/common/error.h"
#include "src/common/readstream.h"

Expand Down Expand Up @@ -91,7 +92,8 @@ void DLGFile::startConversation() {
if (evaluateEntries(_entriesStart, _currentEntry)) {
evaluateReplies(_currentEntry->replies, _currentReplies);

runScript(_currentEntry->script);
runScript(_currentEntry->script1);
runScript(_currentEntry->script2);
}

_ended = false;
Expand All @@ -114,7 +116,8 @@ void DLGFile::pickReply(uint32 id) {
return;

if ((id == kEndLine) || ((_currentEntry == _entriesNPC.end()))) {
runScript(_convEnd);
runScript(_currentEntry->script1);
runScript(_currentEntry->script2);

_ended = true;
return;
Expand All @@ -125,12 +128,14 @@ void DLGFile::pickReply(uint32 id) {
_currentEntry = _entriesPC.begin() + id;
_currentReplies.clear();

runScript(_currentEntry->script);
runScript(_currentEntry->script1);
runScript(_currentEntry->script2);

if (evaluateEntries(_currentEntry->replies, _currentEntry)) {
evaluateReplies(_currentEntry->replies, _currentReplies);

runScript(_currentEntry->script);
runScript(_currentEntry->script1);
runScript(_currentEntry->script2);
} else {
runScript(_convEnd);
_ended = true;
Expand All @@ -153,7 +158,7 @@ const DLGFile::Line *DLGFile::getOneLiner() const {
e != _entriesStart.end(); ++e) {

std::vector<Entry>::const_iterator line = _entriesNPC.begin() + e->index;
if (!line->replies.empty() || !runScript(e->active))
if (!line->replies.empty() || !runScript(line->script1) || !runScript(line->script2))
continue;

return &line->line;
Expand All @@ -168,8 +173,10 @@ void DLGFile::load(const GFF3Struct &dlg) {
_delayEntry = dlg.getUint("DelayEntry", 0);
_delayReply = dlg.getUint("DelayReply", 0);

_convAbort = dlg.getString("EndConverAbort");
_convEnd = dlg.getString("EndConversation");
_convAbort.name = dlg.getString("EndConverAbort");
_convAbort.negate = false;
_convEnd.name = dlg.getString("EndConversation");
_convEnd.negate = false;

_noZoomIn = !dlg.getBool("PreventZoomIn", true);

Expand Down Expand Up @@ -218,7 +225,18 @@ void DLGFile::readLinks(const GFF3List &list, std::vector<Link> &links) {
}

void DLGFile::readEntry(const GFF3Struct &gff, Entry &entry) {
entry.script = gff.getString("Script");
entry.script1.name = gff.getString("Script");
entry.script2.name = gff.getString("Script2");

entry.script1.parameters.resize(5);
entry.script2.parameters.resize(5);
for (int i = 0; i < 5; ++i) {
entry.script1.parameters[i] = gff.getSint("ActionParam" + Common::composeString(i + 1));
entry.script2.parameters[i] = gff.getSint("ActionParam" + Common::composeString(i + 1) + "b");
}

entry.script1.parameterString = gff.getString("ActionParamStrA");
entry.script2.parameterString = gff.getString("ActionParamStrB");

entry.line.speaker = gff.getString("Speaker");

Expand Down Expand Up @@ -251,7 +269,21 @@ void DLGFile::readEntry(const GFF3Struct &gff, Entry &entry) {

void DLGFile::readLink(const GFF3Struct &gff, Link &link) {
link.index = gff.getUint("Index", 0xFFFFFFFF);
link.active = gff.getString("Active");
link.active1.name = gff.getString("Active");
link.active2.name = gff.getString("Active2");

link.active1.parameters.resize(5);
link.active2.parameters.resize(5);
for (int i = 0; i < 5; ++i) {
link.active1.parameters[i] = gff.getSint("Param" + Common::composeString(i + 1));
link.active2.parameters[i] = gff.getSint("Param" + Common::composeString(i + 1) + "b");
}

link.active1.parameterString = gff.getString("ParamStrA");
link.active2.parameterString = gff.getString("ParamStrB");

link.active1.negate = gff.getBool("Not", false);
link.active2.negate = gff.getBool("Not2", false);
}

bool DLGFile::evaluateEntries(const std::vector<Link> &entries,
Expand All @@ -260,7 +292,7 @@ bool DLGFile::evaluateEntries(const std::vector<Link> &entries,
active = _entriesNPC.end();

for (std::vector<Link>::const_iterator e = entries.begin(); e != entries.end(); ++e) {
if (!runScript(e->active))
if (!runScript(e->active1) || !runScript(e->active2))
continue;

assert(e->index < _entriesNPC.size());
Expand All @@ -279,7 +311,7 @@ bool DLGFile::evaluateReplies(const std::vector<Link> &entries,

active.reserve(entries.size());
for (std::vector<Link>::const_iterator e = entries.begin(); e != entries.end(); ++e) {
if (!runScript(e->active))
if (!runScript(e->active1) || !runScript(e->active2))
continue;

assert(e->index < _entriesPC.size());
Expand All @@ -290,23 +322,26 @@ bool DLGFile::evaluateReplies(const std::vector<Link> &entries,
return !active.empty();
}

bool DLGFile::runScript(const Common::UString &script) const {
if (script.empty())
bool DLGFile::runScript(const Script &script) const {
if (script.name.empty())
return true;

try {
NWScript::NCSFile ncs(script);
NWScript::NCSFile ncs(script.name);

ncs.setParameters(script.parameters);
ncs.setParameterString(script.parameterString);

const NWScript::Variable &retVal = ncs.run(_owner);
if (retVal.getType() == NWScript::kTypeInt)
return retVal.getInt() != 0;
return script.negate ? (retVal.getInt() == 0) : (retVal.getInt() != 0);
if (retVal.getType() == NWScript::kTypeFloat)
return retVal.getFloat() != 0.0f;
return script.negate ? (retVal.getFloat() == 0.0f) : (retVal.getFloat() != 0.0f);

return true;

} catch (...) {
Common::exceptionDispatcherWarning("Failed running dialog script \"%s\"", script.c_str());
Common::exceptionDispatcherWarning("Failed running dialog script \"%s\"", script.name.c_str());
return false;
}

Expand Down
26 changes: 15 additions & 11 deletions src/aurora/dlgfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,7 @@ namespace NWScript {
// - Camera: "CameraModel", "CameraAngle", "CameraID", "CamVidEffect", "FadeType"
// TODO: KotOR2:
// - "Emotion", "FacialAnim"
// - 2 scripts, with params:
// "Script{,2}"; "ActionParam[1-5]{,b}", "ActionParamStr{A,B}"
// - 2 active test scripts, with params and bool operators (not, and/or)
// "Active{,2}"; "Param[1-5]{,b}", "ParamStr{A,B}"
// "Not{,2}", "Logic"
// - "Logic"

class DLGFile : boost::noncopyable {
public:
Expand Down Expand Up @@ -110,17 +106,25 @@ class DLGFile : boost::noncopyable {
const Line *getOneLiner() const;

private:
/** A script used by an entry or a link. */
struct Script {
Common::UString name; ///< Name of the script.
std::vector<int> parameters; ///< Parameter to call the script with.
Common::UString parameterString; ///< String parameter to call the script with.
bool negate; ///< Negation of the scripts result.
};

/** A link to a reply. */
struct Link {
uint32 index; ///< Index into the entries/replies.
Common::UString active; ///< Script that determines if this link is active.
uint32 index; ///< Index into the entries/replies.
Script active1, active2; ///< Scripts that determine if this link is active.
};

/** A dialog entry. */
struct Entry {
bool isPC; ///< Is this a PC or NPC line?

Common::UString script; ///< Script to run when speaking this entry.
Script script1, script2; ///< Scripts to run when speaking this entry.

Line line; ///< The line's contents.

Expand All @@ -133,8 +137,8 @@ class DLGFile : boost::noncopyable {
uint32 _delayEntry; ///< Number of seconds to wait before showing each entry.
uint32 _delayReply; ///< Number of seconds to wait before showing each reply.

Common::UString _convAbort; ///< Script to run when the conversation was aborted.
Common::UString _convEnd; ///< Script to run when the conversation ended normally.
Script _convAbort; ///< Script to run when the conversation was aborted.
Script _convEnd; ///< Script to run when the conversation ended normally.

bool _noZoomIn; ///< Starting the conversation does not zoom the camera onto the speaker.

Expand Down Expand Up @@ -162,7 +166,7 @@ class DLGFile : boost::noncopyable {
bool evaluateReplies(const std::vector<Link> &entries,
std::vector<const Line *> &active);

bool runScript(const Common::UString &script) const;
bool runScript(const Script &script) const;
};

} // End of namespace Aurora
Expand Down

0 comments on commit 0b53173

Please sign in to comment.