载入中...
搜索中...
未找到
DialogueUX.cpp
浏览该文件的文档.
2
3#include <cctype>
4#include <simplesquirrel/simplesquirrel.hpp>
5
6namespace eve::dialogue {
7
9
10void DialogueUX::record(const std::string& lineId, const std::string& speaker,
11 const std::string& text) {
12 history_.push_back({lineId, speaker, plainText(text)});
13 if (!lineId.empty()) readLines_.insert(lineId);
14}
15
16void DialogueUX::clearHistory() { history_.clear(); }
17
18int DialogueUX::getHistoryCount() const { return static_cast<int>(history_.size()); }
19
20const DialogueUX::HistoryEntry* DialogueUX::historyAt(int index) const {
21 return index >= 0 && static_cast<size_t>(index) < history_.size()
22 ? &history_[static_cast<size_t>(index)]
23 : nullptr;
24}
25
26std::string DialogueUX::getHistoryLineId(int index) const {
27 const auto* entry = historyAt(index);
28 return entry ? entry->lineId : std::string{};
29}
30
31std::string DialogueUX::getHistorySpeaker(int index) const {
32 const auto* entry = historyAt(index);
33 return entry ? entry->speaker : std::string{};
34}
35
36std::string DialogueUX::getHistoryText(int index) const {
37 const auto* entry = historyAt(index);
38 return entry ? entry->text : std::string{};
39}
40
41namespace {
42
43bool isControlTag(const std::string& tag) {
44 const size_t equal = tag.find('=');
45 const std::string name = tag.substr(0, equal);
46 return name == "pause" || name == "speed" || name == "color" || name == "/color" ||
47 name == "shake" || name == "/shake";
48}
49
50} // namespace
51
52std::string DialogueUX::plainText(const std::string& richText) const {
53 std::string out;
54 out.reserve(richText.size());
55 for (size_t i = 0; i < richText.size();) {
56 if (richText[i] == '[') {
57 const size_t close = richText.find(']', i + 1);
58 if (close != std::string::npos && isControlTag(richText.substr(i + 1, close - i - 1))) {
59 i = close + 1;
60 continue;
61 }
62 }
63 out.push_back(richText[i++]);
64 }
65 return out;
66}
67
68int DialogueUX::getTextActionCount(const std::string& richText) const {
69 int count = 0;
70 for (size_t i = 0; i < richText.size();) {
71 if (richText[i] == '[') {
72 const size_t close = richText.find(']', i + 1);
73 if (close != std::string::npos) {
74 if (isControlTag(richText.substr(i + 1, close - i - 1))) ++count;
75 i = close + 1;
76 continue;
77 }
78 }
79 ++i;
80 }
81 return count;
82}
83
84void DialogueUX::setAutoDelay(float seconds) { autoDelay_ = seconds < 0.f ? 0.f : seconds; }
85
86bool DialogueUX::updateAuto(float dt, bool voicePlaying) {
87 if (!autoMode_ || voicePlaying) return false;
88 autoElapsed_ += dt > 0.f ? dt : 0.f;
89 if (autoElapsed_ < autoDelay_) return false;
90 autoElapsed_ = 0.f;
91 return true;
92}
93
94bool DialogueUX::setSkipMode(const std::string& mode) {
95 if (mode != "off" && mode != "read" && mode != "all") return false;
96 skipMode_ = mode;
97 return true;
98}
99
100void DialogueUX::markRead(const std::string& lineId) {
101 if (!lineId.empty()) readLines_.insert(lineId);
102}
103
104bool DialogueUX::isRead(const std::string& lineId) const {
105 return !lineId.empty() && readLines_.find(lineId) != readLines_.end();
106}
107
108bool DialogueUX::shouldSkip(const std::string& lineId) const {
109 return skipMode_ == "all" || (skipMode_ == "read" && isRead(lineId));
110}
111
112void DialogueUX::expose(ssq::Table& table) {
113 auto cls = table.addClass(name, DialogueUX::create, false);
114 expose(cls);
115}
116
117void DialogueUX::expose(ssq::Class& cls) {
118 cls.addFunc("getName", &DialogueUX::getName);
119 cls.addFunc("record", &DialogueUX::record);
120 cls.addFunc("clearHistory", &DialogueUX::clearHistory);
121 cls.addFunc("getHistoryCount", &DialogueUX::getHistoryCount);
122 cls.addFunc("getHistoryLineId", &DialogueUX::getHistoryLineId);
123 cls.addFunc("getHistorySpeaker", &DialogueUX::getHistorySpeaker);
124 cls.addFunc("getHistoryText", &DialogueUX::getHistoryText);
125 cls.addFunc("plainText", &DialogueUX::plainText);
126 cls.addFunc("getTextActionCount", &DialogueUX::getTextActionCount);
127 cls.addFunc("setAutoMode", &DialogueUX::setAutoMode);
128 cls.addFunc("isAutoMode", &DialogueUX::isAutoMode);
129 cls.addFunc("setAutoDelay", &DialogueUX::setAutoDelay);
130 cls.addFunc("getAutoDelay", &DialogueUX::getAutoDelay);
131 cls.addFunc("updateAuto", &DialogueUX::updateAuto);
132 cls.addFunc("resetAutoTimer", &DialogueUX::resetAutoTimer);
133 cls.addFunc("setSkipMode", &DialogueUX::setSkipMode);
134 cls.addFunc("getSkipMode", &DialogueUX::getSkipMode);
135 cls.addFunc("markRead", &DialogueUX::markRead);
136 cls.addFunc("isRead", &DialogueUX::isRead);
137 cls.addFunc("shouldSkip", &DialogueUX::shouldSkip);
138}
139
140} // namespace eve::dialogue
HSQOBJECT cls
Definition ECS.cpp:21
std::string text
std::string name
const std::string * tag
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:26
std::uint32_t count
uint32_t index
virtual std::string getName() const =0
Returns the name.
Presentation state shared by default and custom dialogue UIs.
Definition DialogueUX.h:14
bool isAutoMode() const
True when auto mode.
Definition DialogueUX.h:39
void setAutoMode(bool enabled)
Sets the auto mode.
Definition DialogueUX.h:37
std::string getHistoryText(int index) const
Returns the history text.
int getTextActionCount(const std::string &richText) const
Number of pause/speed/style actions in rich text.
void clearHistory()
Clears history.
void record(const std::string &lineId, const std::string &speaker, const std::string &text)
Record a completed line in the player-visible backlog.
void resetAutoTimer()
Resets auto timer.
Definition DialogueUX.h:47
bool shouldSkip(const std::string &lineId) const
Should skip.
float getAutoDelay() const
Returns the auto delay.
Definition DialogueUX.h:43
bool isRead(const std::string &lineId) const
True when read.
void setAutoDelay(float seconds)
Sets the auto delay.
bool setSkipMode(const std::string &mode)
Set skip mode: off, read, or all.
std::string getHistoryLineId(int index) const
Returns the history line id.
int getHistoryCount() const
Returns the history count.
bool updateAuto(float dt, bool voicePlaying)
Advance the auto timer; voice playback holds the timer.
std::string getSkipMode() const
Returns the skip mode.
Definition DialogueUX.h:52
void markRead(const std::string &lineId)
Mark read.
std::string getHistorySpeaker(int index) const
Returns the history speaker.
std::string plainText(const std::string &richText) const
Strip supported control tags for plain UI widgets.