yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
story_event_graph_query.cc
Go to the documentation of this file.
2
3#include <cctype>
4#include <sstream>
5
6namespace yaze::core {
7
8namespace {
9
10std::string ToLower(std::string_view input) {
11 std::string out;
12 out.reserve(input.size());
13 for (unsigned char ch : input) {
14 out.push_back(static_cast<char>(std::tolower(ch)));
15 }
16 return out;
17}
18
19std::vector<std::string> SplitQueryTokens(std::string_view query) {
20 std::vector<std::string> tokens;
21 std::string current;
22 current.reserve(query.size());
23
24 for (unsigned char ch : query) {
25 if (std::isspace(ch)) {
26 if (!current.empty()) {
27 tokens.push_back(ToLower(current));
28 current.clear();
29 }
30 continue;
31 }
32 current.push_back(static_cast<char>(ch));
33 }
34
35 if (!current.empty()) {
36 tokens.push_back(ToLower(current));
37 }
38
39 return tokens;
40}
41
42bool AllTokensMatch(std::string_view haystack_lower,
43 const std::vector<std::string>& tokens_lower) {
44 for (const auto& token : tokens_lower) {
45 if (token.empty()) continue;
46 if (haystack_lower.find(token) == std::string_view::npos) {
47 return false;
48 }
49 }
50 return true;
51}
52
53} // namespace
54
56 const StoryEventNodeFilter& filter) {
57 switch (status) {
59 return filter.include_locked;
61 return filter.include_available;
63 return filter.include_completed;
65 return filter.include_blocked;
66 default:
67 return true;
68 }
69}
70
72 std::ostringstream out;
73
74 // Primary identifiers.
75 out << node.id << ' ' << node.name << ' ';
76
77 // Flags.
78 for (const auto& flag : node.flags) {
79 out << flag.name << ' ' << flag.reg << ' ' << flag.value << ' '
80 << flag.operation << ' ';
81 if (flag.bit >= 0) out << flag.bit << ' ';
82 }
83
84 // Locations (include IDs so search can match "0x25"/"0/1" etc).
85 for (const auto& loc : node.locations) {
86 out << loc.name << ' ' << loc.entrance_id << ' ' << loc.overworld_id << ' '
87 << loc.special_world_id << ' ' << loc.room_id << ' ';
88 }
89
90 // Script references and message IDs.
91 for (const auto& s : node.scripts) out << s << ' ';
92 for (const auto& tid : node.text_ids) out << tid << ' ';
93
94 // Misc notes/evidence.
95 out << node.evidence << ' ' << node.last_verified << ' ' << node.notes << ' ';
96
97 // Dependencies (useful when searching by event id).
98 for (const auto& dep : node.dependencies) out << dep << ' ';
99 for (const auto& u : node.unlocks) out << u << ' ';
100
101 return ToLower(out.str());
102}
103
105 std::string_view query) {
106 const auto tokens = SplitQueryTokens(query);
107 if (tokens.empty()) return true;
108
109 const std::string haystack = BuildStoryEventNodeSearchText(node);
110 return AllTokensMatch(haystack, tokens);
111}
112
114 const StoryEventNodeFilter& filter) {
115 if (!StoryNodeStatusAllowed(node.status, filter)) {
116 return false;
117 }
118 return StoryEventNodeMatchesQuery(node, filter.query);
119}
120
121} // namespace yaze::core
122
bool AllTokensMatch(std::string_view haystack_lower, const std::vector< std::string > &tokens_lower)
std::vector< std::string > SplitQueryTokens(std::string_view query)
bool StoryEventNodeMatchesFilter(const StoryEventNode &node, const StoryEventNodeFilter &filter)
bool StoryEventNodeMatchesQuery(const StoryEventNode &node, std::string_view query)
std::string BuildStoryEventNodeSearchText(const StoryEventNode &node)
bool StoryNodeStatusAllowed(StoryNodeStatus status, const StoryEventNodeFilter &filter)
StoryNodeStatus
Completion status of a story event node for rendering.
Filter options for StoryEventGraph node search in UI.
A node in the Oracle story event graph.
std::vector< StoryLocation > locations
std::vector< std::string > unlocks
std::vector< std::string > dependencies
std::vector< std::string > scripts
std::vector< std::string > text_ids
std::vector< StoryFlag > flags